それマグで!

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

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

OSX El Capitan / macOS Sierra からパーミッションの復旧がなくなった

タイトルのとおりです。

El capitan / Sierraからパーミッションの復旧がなくなってSIP( system integrity protection )がメインになってる。

たまに、SIP オフで使ったりするので、パーミッションの復旧がなくなるとめんどくさいことになってる。

パーミッション復旧ツールを見つけた

RepairPermissions V3 – Now supports repairing permissions on macOS Sierra | FireWolf Pl.

導入と実行

ぱぱっとダウンロードしてハッシュチェックします。

curl -LJO http://www.firewolf.science/download/715/
name=( RepairPermissions*.zip )
if [[ ! -f  $name ]] ;then
  exit;
fi
echo $name
hash=$(md5sum RepairPermissions*.zip | awk '{print $1}' );
[[  $name =~ _(.*).zip  ]] ; echo $? ; echo ${BASH_REMATCH[1]};
[[ ${BASH_REMATCH[1]} == $hash ]]; echo $?
unzip $name
chmod +x RepairPermissions

実行

実行してパーミッションを修正する。

sudo RepairPermissions / 

実行結果

RepairPermissions - Verify and repair permissions of an entire volume
Copyright (C) 2016 FireWolf @ FireWolf Pl. All Rights Reserved.

Current OS: OS X El Capitan 10.11.6 (15G1217)
 Target OS: OS X El Capitan 10.11.6 (15G1217)

  Info:  SIP Allow Unrestricted File System [ENABLED]
  Info:  RepairPermissions will repair permissions on /
  Info:  This will take some time. Grab a cup of coffee and be patient.
  Info:  RepairPermissions is running in Normal Mode.
  Info:  Intel(R) Core(TM) i5-4258U CPU @ 2.40GHz 2C4T
  Info:  Available Processors: 4; Will use up to 4 processor(s).
Status:  [ULTRAFAST] Doing some wolf's magics...    Progress: 59.78% [\]
Status:  [ULTRAFAST] Doing some wolf's magics...    Progress: 89.95% [|]
Status:  [ULTRAFAST] Doing some wolf's magics...    [COMPLETED]

これで、多少のことを気にせずにガンガン行けるね。

まぁSIPをオンにすれば戻るんだろうけど。

画像の比較をしてズレがないか調べる

image magick で画像の比較をすることが出来る。

画像の比較をするにはいろいろな方法がある。

  • 目で見てわかりやすい→WEBや校正用
  • 機械的に見てわかりやすい→ダイアログなどプログラムのテスト
  • 画像におおきな影が出る→動体検出

等と大きく分けて使い分けることになると思います。とくに機械学習などで自動化の事前処理に役立つと思います。

元画像1: 1.png

f:id:takuya_1st:20170224170950p:plain:w300

元画像2 : 2.png

f:id:takuya_1st:20170224170905p:plain:w300

機械的に色を見るやり方

比較方法

compare の場合

compare -metric AE 1.png 2.png compare-AE.png

metric による違い

AEとPSNR の違いを見ておきます。キャプチャ画面はAEの方が良さそう。

AE の例

f:id:takuya_1st:20170224171416p:plain:w300

PSNR の例

f:id:takuya_1st:20170224171433p:plain:w300

metric 一覧を見るには

takuya@Desktop$ compare -list metric
AE
Fuzz
MAE
MEPP
MSE
NCC
PAE
PHASH
PSNR
RMSE

composite で画像の差分を見る

compsite コマンドで画像を合成して、差分を明確することも出来る。同じ色だと黒色になる。スクリーンキャプチャに向いてる。

composite -compose difference 1.png 2.png compsite-diff.png

composite diffrence の例

f:id:takuya_1st:20170224171539p:plain:w300

差分量による差異の計算

composie をしたときに、同じ部分は「黒色」に近づくので、より黒色に近いほどに差分がないことがわかる

identify -format "%[mean]" compsite-diff.png
## または 改行とファイル名を含めるなど
identify -format "%[mean], %f\n" compose-difference.png
  • 差分がない:0 に近くなる
  • 差分がある:0からどんどん離れる( 0(黒)〜65535(白)

目で見てわかりやすいやり方。

差を色でわかりやすくする

差分を計算するのとは異なりますが、画像を合成することで、見た目でわかりやすくするテクニックも見つけた。

事前処理で、差分を見る画像に色を付けておくと、少しわかりやすくなる

  • 元画像1:青系
  • 元画像2:赤系

事前処理

convert -type GrayScale +level-colors Red,White 1 .png 1_red.png
convert -type GrayScale +level-colors Blue,White 2.png 1_blu.png

合成処理

convert -compose Multiply -composite 1_red.png 1_blue.png a_b_diff.png

色の見方は次のとおりになる。黒系になれば両方に差分が有り、赤・青なら片方だけに差分がある。

白 × 白 = 白 
白 × 青 = 青
白 × 赤 = 赤
赤 × 青 = 黒

此の考え方だと、片方にしか無いものがより際立ってわかりやすくする事ができる。 事前処理で色数減らすのは頭いいなぁと思う。

サンプル

元画像を2色画像に加工します。

1_red.png : 元画像の赤色化

f:id:takuya_1st:20170224173255p:plain:w300

2_blu.png: 元画像の青色化

f:id:takuya_1st:20170224173300p:plain:w300

diff.png

  • 赤色:元画像1の部分にしか無い箇所
  • 青色:元画像2の部分にしかない箇所

と元画像の差分を視覚的に伝えることが出来ます。

f:id:takuya_1st:20170224173307p:plain:w300

さて何に使う?

  • 画像(動画)を圧縮したときの劣化率具合をみたり
  • 連写の違いをみたり
  • 動体検出の事前処理だったり
  • WEBページのレイアウト崩れだったり
  • WEBの広告枠がきちんと更新されるか
  • 巨大なExcelの細かい数字の違いを探したり
  • ダイアログが修正前後で同じか比較したり
  • イラレ原稿の変更箇所を伝える

画像を比較したら、結構あれこれできそうですよね。

スクリーンショットや、動画からの切り出しは便利ですよね。OpenCVでアコレいじくりまわすときでも複雑なことやら無くて済むので。役に立ちそう

追記

ImageMagick で画像を比較する - awm-Tech によると、SSIMを ffmpegで使うと簡単に劣化具合がわかるらしい

ffmpeg -i image1.jpg -i image2.gif -filter_complex ssim -an -f null -

magick にも限界があるのでffmpeg の利用も考えていきたい。

参考資料

compare コマンドで画像のズレを見つけろ!

ImageMagickにはcompareコマンドがある。

compare コマンドを使うと簡単に画像を比較することが出来る。

これはWebkit2png で取得した画像を使うとレイアウト崩れを見つけられるので嬉しいと思う

画像比較の例

compare -highlight-color red  1.png 2.png out.png

ひと目で差を見つけるのが難しいときも

f:id:takuya_1st:20170224165229p:plain:w150f:id:takuya_1st:20170224165218p:plain:w150

compare しておくとすぐわかる。

f:id:takuya_1st:20170224165224p:plain:w150

他にもいろいろな方法がある

  • compareを使う場合
  • compose を使う場合
  • convert composite を使う場合
  • compose mutipyを使う場合 色で見るのがわかりやすい
  • compose differenceを使う場合
  • compose AEを使う場合

参考資料

http://qiita.com/y_hokkey/items/417e108e212210b4e635#_reference-69fdebdf51dc682e5b67

/etc/passwd を編集しても反映しなかった。→ usermod を使う

/etc/passwd を手で編集した。

なぜだかわからない。反映しない。手作業で編集は駄目だと思ったけどshellや home dir や gid をマトメて編集できるから、もう直接手で触ればいいやとおもったけど反映しない。

home_dir を変更しても反映しない。。。再起動が必要だった。

シンタックスエラーはなかった

編集後にチェックして特にエラーがないことを確認

sudo pwck

専用コマンドを使うほうが無難だと思われる

ユーザーを操作するのは、専用コマンドを使ったほうが無難だと思う。

  • vipw
  • vipw -s
  • chsh
  • chfn
  • usermod
  • pwck

usermod であれこれ変更

usermod が便利なのでパターンとして覚えておくほうがいい

ホームディレクトリを変更

ホームディレクトリを別の場所に作り直す

usermod -d /var/home/takuya takuya

ホームディレクトリを移動

現在のホームディレクトリを指定の場所に移動させる。次からは指定の場所を使う。

usermod  -m -d /var/home/takuya takuya

シェルの変更

デフォルトシェルの変更。これはchsh でも出来る

usermod -s /bin/false takuya

ユーザーをロックする

ロックしてログインできなくする。

usermod -L takuya 

ユーザーをアンロックする

ロックしたユーザーを解除する

usermod -U takuya 

ユーザ名を変更する

ユーザ名を変更すると //home` も変更しないとログイン後にホームディレクトリが見つからないなどの問題が出てくるので注意

usermod -l takuya_1st takuya

設定の反映

ログイン中は設定が反映しないので、一旦ログアウトする必要がある。

/etc/{passwd,shadow}が間違ってないか

シンタックスエラーや記述ミスをチェックする

sudo pwck

/etc/passwd を編集する

sudo -e /etc/passwd はどうもうまく動かない*1なので vipw を使う

sudo vipw

参考資料

  • man usermod
       usermod  コマンドは、 コマンドライン上での指定によって、 システムアカウントファイルを修正する。 usermod コマン
       ドに指定できるオプションは次の通り。

       -c comment
              パスワードファイルのコメントフィールドに与える新しい値。 通常は chfn(1)  ユーティリティによって変更され
              る。

       -d home_dir
              新しいログインディレクトリ。 -m オプションを用いると、 現在のホームディレクトリの中身が新しいホームディ
              レクトリに移動される (後者が存在しない場合は新たに作成される)。

       -e expire_date
              そのユーザアカウントが使用不能になる日付。 日付は YYYY-MM-DD という書式で指定する。

       -f inactive_days
              パスワードの使用期限が切れてからアカウントが永久に使用不能になるまでの日数。 0 にすると、  パスワードの
              期限が切れると同時にこのアカウントは使用不能になる。   -1  にするとこの機能が無効になる。デフォルト値は
              -1。

       -g initial_group

              新たにそのユーザのログイン時初期グループとするグループ名または ID。  グループ名は既に存在していなければ
              ならない。 グループ番号は既存のグループを参照していなければならない。 デフォルトのグループ番号は 1。

       -G group,[...]
              ユーザが属する補助グループ (supplementary groups) のリスト。 グループはコンマで区切り、間に空白文字を入
              れてはならない。 指定できるグループには -g オプションと同様の制限がある。 現在そのユーザが、 新しいリス
              トにないグループのメンバーになっている場合は、 そのグループから削除される。

       -l login_name
              ユーザのログイン名を login から login_name に変更する。 他は何も変更しないので、 おそらく新しいログイン
              名に合わせて ホームディレクトリの名前を変更する必要があるだろう。

       -p passwd
              crypt(3) の返り値である暗号化パスワード。

       -s shell
              ユーザの新しいログインシェルの名前。 このフィールドを空白にした場合は、  システムがデフォルトのログイン
              シェルを選択する。

       -u uid ユーザの ID 番号。 この値は、-o オプションを用いる場合を除き、他と重複してはならない。 また非負値でなく
              てはならない。 0 から 999 までの値は、通常システムアカウント用に予約されている。 ホームディレクトリ以下
              の、 そのユーザ所有のすべてのファイルのユーザ ID は、 自動的に新しい値に変更される。 ホームディレクトリ
              以下にないファイルは手作業で変更しなければならない。

       -L     ユーザのパスワードをロックする。 これは暗号化されたパスワードの前に '!' を追加し、 実質的にパスワードを
              無効にする。 このオプションを -p や -U と同時に用いることはできない。

       -U     ユーザのパスワードをアンロックする。 これは暗号化されたパスワードの先頭の '!' を取り除く。 このオプショ
              ンを -p や -L と同時に用いることはできない。

*1: systemd になったあたりから、systemd 関係してる?

ネットワークのIPアドレスを一覧表示する(sort でIPアドレスをソート)

ローカルネットワークのIPを列挙する

nmap を使って、ネットワークに疎通できるIPアドレスがどれだけあるか見ておく

takuya@Desktop$ nmap -sP 192.168.2.0/28 | /usr/bin/grep -o '192.168.2.\d' 
192.168.2.1
192.168.2.2
192.168.2.3
192.168.2.9

うちのローカルネットワークだと1−9の数台しか使ってないのであまり違いが出ない

sort であれこれソートできる

もっとたくさんのIPアドレスが出てくる場合はソートしないといけない

IPアドレスは、バージョンの記述に似ているので、バージョン番号でソートする機能と同じように使える。

sort -V 

やってみた。

takuya@Desktop$ for i in {1..10}; do echo  192.168.$(( $RANDOM%254 )).$(( $RANDOM%254 )) ; done  | sort  -V
192.168.54.9
192.168.88.230
192.168.91.181
192.168.105.133
192.168.130.186
192.168.134.246
192.168.153.65
192.168.185.8
192.168.240.5
192.168.250.31

うん、きれいに数値順にソートされる。

javascriptで名前空間を作って生産効率を上げる

名前空間の利用

名前空間を利用するとJavaScriptがもっと楽しくなる。

何でもかんでも、Globalなオブジェクトに登録していくと、どうしても限界が早くなる。

コードを書くよりもコードを読むのに時間がかかるという点です。問題に深く集中して売る時、腰を据えて午後の時間をかなりの量のコード作成に費やすことが出来ます。その為に「namespace」による管理は、管理コストを下げ共同作業をやりやすくするという点において最高ですね。

global だと変数名の衝突も置きて頭抱えることになる。

名前空間のはじめの一歩。

var takuya = {};

なければ作る名前空間

var takuya = {}; が2度呼び出されると、初期化されてしまうので、名前空間が破壊されてしまう。

そこで次のようにする。

シンプルで美しい

var takuya = takuya || {}

ベターなやり方

ちゃんとチェックしてもいいけどめんどくさいよね。

if ( typeof takuya == 'undefined' ) {
  var takuya = {};
}

複数個の namespace をどうするんだい

いくら シンプルで美しい 書き方でも、何度も書くと冗長すぎる・・・

var takuya = takuya || {}
var takuya.arrays  = takuya.arrays || {}
var takuya.utils   = takuya.utils || {}
var takuya.connect = takuya.connect || {}
var takuya.logins  = takuya.logins || {}

ちょっと関数を作っておきます。

function define_namespace( path ){
    var paths = path.split('.')
    var namespace = ''
    var _global = this;//window or global
    paths.reduce( function(prev,curr) {
      if ( !prev.hasOwnProperty(curr) ) {
        prev[curr] = {}
      }
      curr = prev[curr];
      return curr ;
    }, _global )
}

これで、マルっとオブジェクト作れますね

define_namespace('takuya.maps.drawing.lines.point')
console.log( takuya )
console.log( takuya.maps )
console.log( takuya.maps.drawing )
console.log( takuya.maps.drawing.lines )
console.log( takuya.maps.drawing.lines.point )

名前空間を使ったモジュール関数を作る。

名前空間を作ってモジュール化できることがわかったので、モジュール関数を作る

define_namespace('takuya.blog.sample')
takuya.blog.sample.log = function(e){
  console.log(e)
}
takuya.blog.sample.log('Hello from module func')

まぁ当たり前でですね。

名前空間を使ったモジュールにコンストラクタを作る

define_namespace('takuya.blog')
takuya.blog.Book = function(name){
  this.name = name 
  this.getName = function getName (){
    return this.name
  }
}
var book = new takuya.blog.Book('Hello from module constructor')
console.log(book.getName())

名前空間に定数を作る?

定数は存在しないので、大文字で書いて、定数であることを明示するくらいしか出来ない。

define_namespace('takuya.screen')
takuya.screen = {
  MAX_WIDTH: 1280;
  MAX_HEIGT:  720;
}
takuya.screen.MAX_HEIGHT;

参考資料

JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法

https://www.amazon.co.jp/JavaScriptパターン-優れたアプリケーションのための作法-Stoyan-Stefanov/dp/4873114888/ref=sr_1_1?ie=UTF8&qid=1487917553&sr=8-1&keywords=javascript+パターン

JavaScriptでプライベートな変数やメソッドを作る

プライベートなメンバを作る

プライベートメンバを作るには、どうするか?

プライベート・メンバを作るパターンが基本パターンとして次があげられる。

function Phone() {
  //プライベート・メンバ
  var name = 'Xperia'
  //パブリック・メンバ
  this.getName = function(){
    return name;
  }
}

プライベートな変数を作るのに、変数のスコープを使う。

まぁ、出来るんだけど、スコープの限界があるんので そこは仕方ないかもね

実行例はこちら

> my_phone = new Phone
Phone { getName: [Function] }
> my_phone.name
undefined
> my_phone.getName()
'Xperia'
>

ただしここも参照コピー問題。

function Phone() {
  //プライベート・メンバ
  var info = {name:"Xperia"}
  //パブリック・メンバ
  this.getInfo = function(){
    return info;
  }
}
my_phone = new Phone
var i = my_phone.getInfo();
i.my_name = 'takuya'
my_phone.getInfo()

実行結果

> var i = my_phone.getInfo(); 
> i
{ name: 'Xperia' }
> i.my_name = 'takuya'
'takuya'
> my_phone
Phone { getInfo: [Function] }
> my_phone.getInfo()
{ name: 'Xperia', my_name: 'takuya' }
>

すべてが参照ってのも怖いね。スコープの内部にアクセスできちゃうんですよね。

まぁ最近の更新で何か新機能が追加されてることを願おう

Object.assign は何をする為にあるんや?

Object.assign が使えるようになってる。

Object.assign() - JavaScript | MDN

Object.assign(target, ...sources)

せっかくなので調べてみて、ソースコードの重複が減らせるのに使えるか調べてみた。

Object.assign は何をするのか

var a = { age : 17 }
var b = {name:'takuya', age: 19 }
var c = Object.assign( a,b )

console.log( c )

実行結果

{ age: 19, name: 'takuya' }

a に b を上書きする。ハッシュの結合とも言える。

連想配列を結合するときに Object.assign が便利コレ。

また、データと操作を別に作っておいて

クラスを new する感じにも使える。

コンストラクタで初期化データを渡してオブジェクトをnewして、データをいれて初期化する基本パターンを手軽に書くという意味においては便利

コンストラクタで、初期データを投入するパターン

Java で初級者が習う、コンストラクタで初期化するパターン

class Person {
  public String name;
  public String age;
  public Persion ( name, age ) {
    this.name = name ;
    this.age= age;
  }
  public static void main (String args[]) {
    Person p1 = new Person( "takuya", "19" ) 
  }
}

これをJSで書くとこんな感じになってめんどくさい。

var Person = function Person( name,age ){
  this.name = name;
  this.age  = age;
  this.say = function say (){ return (`Hello , I'm ${this.name}`) }
}
var p1_data = { name: 'takuya', age: 19 }  //← めんどくさい
var p1 = new Person( p1.name, p1.age ) //← めんどくさい

プロパティをEnumerationしていちいち突っ込むのがめんどくさいよね。

Object.assgin を使うと楽ができる。

var Person = {
    say: function () { return (`Hello , I'm ${this.name}`) }
}
var json_str = '{ "name":"takuya", "age": 19 }'

var c = Object.assign( JSON.parse(json_str) , Person )
console.log( c )
console.log( c.say() )

実行結果

{ name: 'takuya', age: 19, say: [Function: say] }
"Hello , I'm takuya"

Object.assign の多重利用( Mix-in )

複数のメソッドをもつオブジェクトに多重継承的にやりたいときも便利

var json_str = '{ "name":"takuya", "age": 19 }'
var c = Object.assign( JSON.parse(json_str) , {} )
var Person = {
      say: function () { return (`Hello , I'm ${this.name}`) }
}
var User = {
      'is_成年': function () { return this.name >= 20; }
}
c = Object.assign( c , Person )
c = Object.assign( c , User )

console.log( c )
console.log( c.say() )
console.log( c.is_成年() )

ネストした場合にどうなるのか

オブジェクトがネストしている場合、assign するとどうなるのか。

deep copy を期待すると出来ない。参照になる。

var person_01 = { name: 'takuya', address: { pref:'osaka' } }
var person_02 = { name: 'yakuta' }
c = Object.assign( person_01 , person_02 )
console.log( c )
// => { name: 'yakuta', address: { pref: 'osaka' } }
person_01.address.pref = 'kyoto'
console.log( c ) 
// =>  { name: 'yakuta', address: { pref: 'kyoto' } } # 参照コピーなので変わっちゃう

ディープコピーを意図しても参照扱いになって、ちょっと面倒になる。この辺は非常に使いづらい気がする。

他にも prototype の扱いに注意。

var Person = function Person( name,age ){
  this.name = name;
  this.age  = age;
  this.say = function say (){ return ("Hello , I'm "+this.name+"." ) }
}

p1.__proto__ //Person {}
p2 = Object.assign( {}, p1  ) 
// => { name: 'takuya', age: 19, say: [Function: say] }
p2.__proto__ //  {}
p1.name //'takuya'
p1.name = 'ya'  //'ya'
p2.name // 'takuya'

コピーされるのは、最上位のオブジェクトだけで、かつfor .. in列挙可能 な物に限られる。 prototype はコピーされない。

コピーされるのは、次のもの

// #### TODO 要確認
for ( i in a ) {
 if( a.hasOwnProperty( i ) ) {
   console.log(i)//ここに制御くるやつ
 }
}

コンストラクタの代わりに突っ込む

冒頭の例の、コンストラクタの代わりに突っ込んでassign することも出来るが。。。実はかえって面倒なことになる可能性を秘めている。

deep copy と参照問題で余り使い所はないかもしれない。

コレくらいのかんたんな結合なら全く問題ない。

// Person { name: undefined, age: undefined, say: [Function: say] }
Object.assign( p1, {name:'takuya'} )
// => Person { name: 'takuya', age: undefined, say: [Function: say] }
p1 = Object.assign( p1, {name:'takuya', age: 19} )
// => Person { name: 'takuya', age: 19, say: [Function: say] }

ただし、これを延長したりネストしたオブジェクトを使うと、途端に考えることが増えてめんどくさくなる。

なので、使い捨てJSON.parse(str) や shallow copy を拡張するのに限りとても便利だと思われる。

安全なObject.assign

prototype がコピーされない、参照コピーになってしまう。このあたりを考慮しObject.assign() を使うと new して 即時オブジェクトをAssignすることになる。

// # 使い捨てなので参照を間違って書き換える心配はない その1
var c = Object.assign( new Person() , JSON.parse(json_str) ) 
// # 使い捨てなので参照を間違って書き換える心配はない その2
var c = Object.assign( new Person() , {name:'takuya', age: 19, type: { user: true }} ) 
// # 浅いコピーなので問題ない。
var a = {name:'takuya', age: 19}
var c = Object.assign( new Person() , a ) 

まとめ

  • Object.assign は {} を結合するのに便利
  • ただし、深いコピーは出来ない
  • 浅いコピーは出来るが、深い部分は参照コピーになって不便
  • __proto__ など列挙されないものは、コピーされない
  • 変数同士の結合は参照の書き換えでバグる可能性がある。
  • JSON.parse()の結果にメソッド生やすのに便利
  • 逆手に取れば、生やしたメソッドを参照共有してくれるので便利。

此のままでは使いにくいので、なにかラッパーを噛ませる。たとえば再帰的にコピーするとか、プロトタイプをコピーするような関数と組み合わせたら便利に使える気がする。まぁそのへんはフレームワーク側がいいようにやってくれるんだろうと期待しておく。

浅いコピーのあたりを油断してassignをガンガン使うと、この先の仕様変更で技術的負債になりそうな気がする。

今回は、prototype に assign するようなことは試してないので今後試してみたい

divのポインタイベントの停止をCSSでやるpointer-events(クリック禁止を手軽にやるCSS)

CSSマウスポインタのイベントを全部disabledにすることが出来る

  pointer-events: none;

なぜ無効化するのか

div を複数枚重ねてて、前面のイベントを無視したいとか、Divを透過させててクリックイベントを暴発させたくない時がある。

サンプル1: ポインタイベントを解釈する場合

イベント登録しているので、クリックするとログに書かれます。

    document.querySelector('div.sampleBox2 > div.wrapper').addEventListener('click', function(e){
      sample_box1_console.log('b','wrapper click');
      
    });
    document.querySelector('div.sampleBox2 > div.wrapper > div.box1').addEventListener('click', function(e){
        sample_box1_console.log('a','box1 click');
    })

サンプル2 クリックなどのポインタ動作を無視する

イベント登録しているけど、何も起きない例です。CSSを入れたのがコレです。

  pointer-events: none;

propagation するので、イベントが透過する。

もちろんPropagationがあるのでイベントがバブリングして透過するので、前面のイベント拾っても後ろに 透過するんです。

透過Divのクリックイベントも透過させることは最初から出来るので

前面のdiv側にpointer-events: none;を入れてやれば、前面のDIVのイベントハンドラ登録はそのままで一気に無効化出来る。

透過Divのクリックイベント透過させるように見せかけられるとうわけだ

何に使うの?

スクロール中の Hover イベントの暴発を防いだり、ボタンを一時的に押せなくしたり。ドラッグ中の暴発を防いだり。とにかく便利ですね。

コンテンツのコピペ防止に使うため?(てかその目的には使えない)

参考資料

https://developer.mozilla.org/en/docs/Web/CSS/pointer-events

iOSの画面をMacに表示してプレゼンで手軽に使いたい

iOSの画面をプレゼンしたい。

プレゼン中に、iOSの画面をだしてデモを手軽行いたい。 どうやるのか、調べたら、Mac があればとても簡単にできることがわかった。

QuickTime Player を使う。

MacがあればiOSの画面収録が簡単です。

  1. Lightning Cableで iOSMacを接続
  2. MacQuickTimeを起動
  3. QuickTimeで新規ムービー収録
  4. バイスiOSが出てくるので接続
  5. iOSのロックを解除

これだけで手軽にiOSの画面をプレゼン用に使えます。

録画は押す必要はないです。

実際にやってみたサンプル

youtu.be

iTerm でダブルクォートで囲まれた文字を選択したい

ダブルクォートで囲まれた文字列を選択したい

json とか ダブルクォートで囲まれた文字列を選択してコピーしたいんだけど、ダブルクォートを文字列の一部として取り出すのでちょっとめんどくさいことが多い

調べたら、4回クリックで選択できるようになってる。

初期設定

初期設定を確認したら次のようになっていた。

Preferences -> Profiles -> Advanced -> Smart Selection

f:id:takuya_1st:20170215220627p:plain f:id:takuya_1st:20170215220621p:plain

bashのブレース展開の変数置換でPATHをぱぱっと確認する。

PATHってパット見でわからないので整形したい。

echo -e ${PATH//:/'\n'}

実行結果

takuya@~$ echo -e ${PATH//:/'\n'}
/Users/takuya/.pyenv/shims
/Users/takuya/.pyenv
/Users/takuya/.bin
/usr/local/sbin
/usr/local
/opt/X11
/usr/sbin
/usr
/sbin

/Users/takuya/.rbenv/shims
/usr/local/share/npm

ああ。楽ちん。

これを関数にしておこう

function path_show(){
  echo -e ${PATH//:/'\n'}
}

いままで、rubyワンライナーでやってたけど

echo $PATH | ruby -aF: -ne "puts \$F"

bash の展開のほうが圧倒的に楽ですね。

IFSを使うなら

IFS=':'
for i in $PATH ; do echo $i; done
/Users/takuya/.pyenv/shims
/Users/takuya/.pyenv/bin
/Users/takuya/.bin
/usr/local/sbin
/usr/local/bin
/opt/X11/bin
/usr/sbin
/usr/bin
/sbin
/bin

/Users/takuya/.rbenv/shims
/usr/local/share/npm/bin

などと出来る。

webkit2png が mac OSX 10.11以降で動かないので対策

webkit2png を使おうとしたら動かない。

エラーは以下の通り。

2017-02-14 17:55:36.413 Python[96859:6854691] Can't open input server /Library/InputManagers/MultiClutchInputManager.bundle
Fetching http://auctions.yahoo.co.jp ...
2017-02-14 17:55:36.461 Python[96859:6854754] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
 ... something went wrong: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.

動かない理由

El capitan 以降 sierra も、iOSと同じで アプリ側のHTTP の通信がブロックされる、webkit2png はPython で内部的に AppKit を使ってるんドエこの影響を受ける。

対策1

http を使わない

webkit2png http://auctions.yahoo.co.jp/ 

コレがエラーになるので、HTTPSを使うようにする

webkit2png https://auctions.yahoo.co.jp/ 

対策2

webkit2png が動かないときは、Configuring App Transport Security に例外を適用する。

このコードを適当なところに書いておく、

from objc import YES
from AppKit import NSBundle
bundle = NSBundle.mainBundle()
info = bundle.localizedInfoDictionary() or bundle.infoDictionary()
info['NSAppTransportSecurity'] = {'NSAllowsArbitraryLoads': YES}

私は、この辺に書いた

 34 try:
 35     import Foundation
 36     import WebKit
 37     import AppKit
 38     import Quartz
 39     import objc
 40     ## 2017-02-14 by takuya
 41     from objc import YES
 42     from AppKit import NSBundle
 43     bundle = NSBundle.mainBundle()
 44     info = bundle.localizedInfoDictionary() or bundle.infoDictionary()
 45     info['NSAppTransportSecurity'] = {'NSAllowsArbitraryLoads': YES}

iOSでHTTPでアクセスできないのは理解できるんだけど、Mac側にもポートされると、ちょっと不自由なOSになりましたね。

参考資料

ファイルサイズを取得し、変数に格納する

rubypython からすぐ出来るんですが、bashでやると面倒ですね

ruby

File.size( 'path/to/file' )

python

import os 
os.path.getsize('path/to/file')

bash

どうやるの? ls -l だと余計なものが多いし。。。まさか、cut してgrep する〜?awkする?

いくつかあるけど stat が良さそう

stat -c %s path/to/file

コレを使って

size=$(stat -c %s path/to/file)

まとめ

ほかにも du -k ls -l wc -c なども考えられる。

ぱっと思いついただけで以下の通り。

ls -l path/to/file | cut -d ' '  -f 5
du --apparent-size --block-size=1  path/to/file
wc -c  < path/to/file
find path/to/file --printf=%s
ruby -e 'puts  File.size  ARGV[0]' path/to/file
  • du だとブロックサイズを意識するのが面倒ですね。
  • ls は cut と組み合わせるのが面倒ですね。
  • rubyワンライナーも面倒ですねぇ
  • find は stat とやってること変わらないから面倒ですねぇ。引数位置とかも。
  • wc はありですねぇ

参考資料

http://unix.stackexchange.com/questions/16640/how-can-i-get-the-size-of-a-file-in-a-bash-script

curl でよく使う設定をまとめる ~/.curlrc

curl の基本設定ファイルを作ることが出来る

~/.curlrc

Default config file, see -K, --config for details.

.curlrc に書く書き方は -K で指定する config ファイルと同じ

curl の毎回指定するのめんどくさいオプションを書いておくと楽

とくに、CookieやUser-Agentなど毎回付けるのが面倒なので、config を作ると楽になる。

とりあえず作った

## デフォルトでつけるよくあるヘッダ
header = "Accept-Encoding: gzip, deflate, sdch"
header = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.76 Safari/537.36"
header = "X-Config-File: ~/.curlrc"

--compressed

X-Config-File は 自分でも curlrc をつけていることを忘れることがあるので、-v した時に気づくように追加しておいた。

gzip / deflate 圧縮を有効にする

header = "Accept-Encoding: gzip, deflate, sdch"
--compress

gzip/deflate で転送しつつ、 --compress で 圧縮されたレスポンスを展開して取得して表示する。

2017-02-15 追加

Cookie も毎回指定するならめんどくさいので、設定に書くことにした。

## cookie
cookie-jar =  /Users/takuya/.curl_cookies
cookie     =  /Users/takuya/.curl_cookies

設定の書き方

どうやらこういう書き方をするといいらしい。

-c path--cookie-jar path とも書くことが出来る。これを cookie-jar = path と書くことが出来る。

これは以下のように読み替えていけばいい

  • -c path
  • --cookie-jar path
  • cookie-jar = path ← 設定ファイル

同じように -b のオプションも同じですね。

  • -b path
  • --cookie path
  • cookie = path ← 設定ファイル

つまり、header の場合はこれを使うと

  • -H value
  • --header value
  • header = value

などと書くことが出来るようですね。

2017-04-11 追記

curlrc がずっと読まれちゃってCookieが維持されちゃうときなど、一時的にcurlrc を無効にしたいときは

curl -q  http:/...

-q オプションを付けることで curlrc の読み込みを一時停止してコマンドを実行することが出来る。

2018/02/15 追加

curlrc はどんなときでも読み込まれる。次のように、明示的にconfig を指定していても ~/.curlrc は読み込まれる。

curl --config yet-another-config  

なので、別の設定ファイルを明示するときや素のcurl が欲しい時は -q をかならず使う。

curl -q  --config yet-another-config  

-q を忘れないようにすること。

更に、-q は最初につける

## これはダメ
curl -v -q 
## これはOK
curl -q -v 

-q オプションは最初につけること

2018-02-04 改訂

compressed になった。

2019-07-22 追記

-K -q の仕様について追記

参考資料

man curl