Hatena::ブログ(Diary)

ザリガニが見ていた...。 このページをアンテナに追加 RSSフィード

2015-06-10

YosemiteでiDVDを使う

前回からの続き。

最近のAppleマシンにはDVDドライブも搭載されていないし、いつの間にかiDVDも添付されなくなってしまった。今後のことを考えると、iMac 5K OSX 10.10 Yosemite環境でもiDVDを使えたらいいなと。現在、古いMacBook OSX 10.6 Snow LeopardでiDVDを使える環境がある。試してみた。

iDVDが標準添付されていた期間

iDVD標準添付iDVDなし
MacBook2010-05 発売開始モデルまで2015-04 発売開始モデルから
MacBook Pro2011-02 発売開始モデルまで2011-10 発売開始モデルから
MacBook Air2010-10 発売開始モデルまで2011-07 発売開始モデルから
iMac2010-07 発売開始モデルまで2011-05 発売開始モデルから
Mac mini2010-06 発売開始モデルまで2011-07 発売開始モデルから
Mac Pro2010-07 発売開始モデルまで2012-06 発売開始モデルから
  • iDVDは2010年度の第4四半期まで、アップルが発売するマシンに標準添付されていた。
  • そして、2011年度以降の新モデルが発売になると、ひっそりとその姿を消していった。

さらば、iDVD...。

古い環境からインストール

  • 古いMacBook OSX 10.6環境から以下のファイルをコピーしてみると、iMac 5K OSX 10.10環境でもiDVDが起動した。
ファイルパス役割
/Applications/iDVD.appアプリケーション本体
/Library/Application Support/iDVD/テーマ
/Library/Documentation/Applications/iDVD/ヘルプ >> スタートアップガイド
  • 標準添付されなくなったのだけど、最新モデルのOSX環境でも、iDVD関連のファイルを移行すれば、立派に使えるのだ!

  • 但し、DVDに書き込めるドライブが搭載されていないので、編集作業はできるけど、DVDの作成はできない、と警告される。

f:id:zariganitosh:20150609061408p:image:w225

  • 試しに古いMacBookのSuper Driveをリモートドライブに指定してみたが、DVDは焼けなかった。
    • どうやらリモートドライブは読み込み専用のようだ。
    • 書き込み用途ではドライブを認識してくれなかった。

  • USB接続の外付け光学式ドライブを購入すれば、iMac 5KでもDVDを焼けるようだ。
  • 当面は古いMacBookのSuper Driveが健在なので、DVDを焼く時だけ古いMacBookを使ってもいい。
    • iMacで編集して、DVDイメージファイルまでは作成できるようだ。
    • それをファイル共有などして、古いMacBookからDVDを焼くのだ。

アップデータからiDVDアプリケーション本体を取り出す

iDVD 7.1.2から取り出す方法
$ cd ~/Downloads
$ pkgutil --expand "/Volumes/iDVD 7.1.2 Update/iDVD7.1.2Update.pkg" iDVD7.1.2Update
$ cd iDVD7.1.2Update/iDVD7.1.2Update.pkg
$ ditto -x --bom Bom Payload ..
$ cd ..
$ open Applications
  • ~/Downloads/iDVD7.1.2Update/Applications/以下にiDVD.appが生成されている。
iDVD アップデート 7.0.4から取り出す方法
  • アップル - サポート - iDVDダウンロードからiDVD アップデート 7.0.4をダウンロードする。
  • iDVD704.dmgを開く。
  • iDVD_704.pkgを選択して、パッケージの内容を表示する。
  • Contents/Archive.pax.gzをダブルクリックして解凍する。
  • ~/Downloads/Archive/以下に、iDVD関連ファイルが生成されている。

しかし、iDVD.app本体は取り出せるのだけど、テーマファイルがない!

  • iDVDを活用するためには、利用可能なテーマが最低一つは必要なのだ。
    • テーマがないと、プロジェクトは始められず、終了するしかない...。
    • あるいは、テーマファイルが壊れていると、プロジェクトを始めた瞬間に強制終了してしまう...。

テーマのないiDVDなんて、地図データのないナビシステムのようなものだ!

iDVD エクストラコンテンツ 1.0

もし、なんらかの方法でiDVDのテーマをインストールできれば...

  • iDVD 1.0〜5.0のテーマをソフトウェアアップデート経由でダウンロードできる。
    • iDVD エクストラコンテンツ 1.0は、OSX 10.8 Mountain Lionまでの環境で利用可能。
    • OSX 10.9 Mavericks・OSX 10.10 Yosemite環境では、ダウンロードできなかった。
  • iDVD.appを起動する。

f:id:zariganitosh:20150609143701p:image:w450


  • 新規プロジェクトを作成する。

f:id:zariganitosh:20150609144002p:image:w225


  • 従来のテーマのどれか、例えばベイビーモールなど選択すると、

f:id:zariganitosh:20150609144213p:image:w450


  • 追加のテーマセットのダウンロードを勧められるので、今すぐダウンロードする。

f:id:zariganitosh:20150609144256p:image:w450

      • ちなみに、OSX 10.9 Mavericks・OSX 10.10 Yosemite環境でもダウンロードは勧められるのだけど、
      • この後のソフトウェアアップデートで、iDVD エクストラコンテンツ 1.0が候補として表示されなかった...。

  • iDVD エクストラコンテンツ 1.0のアップデートを実行する。

f:id:zariganitosh:20150609145347p:image:w450


アップデートが完了すると...

  • iDVD 1〜5のテーマ(4:3標準ビデオ用)が使えるようになっている!
    • しかし、iDVD 6〜7のテーマ(ワイド画面ビデオ用)はインストールされていない。
    • Cineme ChaptersやForever Mainなどはテーマファイルが不完全なので使えない。

f:id:zariganitosh:20150609151017p:image:w450

iLifeからインストール

  • 現在もまだ、iLife 11は販売されていた。

  • その中にiDVD v7.1が含まれているのだ。
  • iDVDは素晴らしいアプリケーションである。
  • iDVDのために購入しても悪くない気がする。
      • しかし、iDVD 6のテーマも含まれるかどうかは不明。
      • Yosemiteに直接インストールできるかどうかも不明。

MacBook付属のインストールディスク

  • 2008年10月発売のMacBookのインストールディスクには、以下の環境が含まれている。
  • カスタマイズボタンを押して、iDVD エクストラコンテンツまで含めておくことで、iDVD 1.0〜7.0すべてのテーマがインストールされる。
  • iDVDのバックアップ用にOSX 10.5.4とiDVD 7.0.2をインストールしておいた。
    • 実験用の外付けHDのパーティションにインストールした。
  • さらにOSX 10.6.8にアップデートして、iDVD 7.1.2にアップデートしておいた。
    • IDVD 7.1.2のアップデートには、OSX 10.6.7以降が必要。

完全なiDVD 7.1.2をバックアップしておくのだ。

2015-06-08

DVDのレーベル印刷

前回からの続き。

DVDは焼けた。しかし、さすがにレーベル面が真っ白なままでは味気ない。配る人も、受け取る人も、何のDVDか分からないし、管理に困ってしまう。やはりレーベル面もちゃんと印刷する必要がある。ちゃんと仕上げるとなると、このプリント作業も面倒。幸いレーベル印刷できるプリンターは持っている。しかし、使ったことないし...。案の定、何度か印刷で失敗して、追加でDVDを焼き直して、もう一度印刷を繰り返すことに。面倒なルーチンにハマってしまった。そうならないために、メモを残すのだ。

作業環境

内径・外径の設定(command-M)

内径23mm
外径118mm
  • DVD-Rのパッケージに書かれた印刷範囲にしておくのが良さそう。

f:id:zariganitosh:20150606110804j:image:w225

  • 失敗(成功の元)
    • 最初、はみ出ないように印刷範囲を小さめに設定してしまった。
    • 内側と外側に白いレーベル部分が残ってしまい、全然ダメな仕上がり。
  • 印刷範囲が最大化するように設定したほうが良い。
    • 白いレーベル面が1mmでも残ってしまうと見栄えが悪いので。
  • 設定の保存をしておくと、次回以降、設定の一覧から選択できる。

レーベル面の作成

  • 表示 >> 200%にしておいた方が、細部まで確認しやすい。
  • 画像を貼り付けるには、以下のどちらかで行う。
挿入 >> 背景...挿入 >> イラスト...
f:id:zariganitosh:20150606142150p:image:h225f:id:zariganitosh:20150606142148p:image:h225
  • レーベルをコピーする場合、どちらで挿入しても印刷結果は同じである。
      • ちなみに、EP-704AにはDVDレーベルをコピーする機能がある。(コピーモードにして、メニューボタンを押して選択する)
      • それを使えばプリンタのメニュー操作だけでレーベルのコピーが完了する。
  • 但し、独自にデザインする場合は...
    • レーベル全体を覆う大きな画像は、背景として指定する流儀のようだ。
    • その背景に、文字・イラスト・直線・円・四角形などを部分的に挿入するのだ。
  • そのように使った方が仕上がりの状態が目に見えるので、直感的に作業できる。
  • 利用可能な素材は、/アプリケーション/Epson Software/Print CD/以下に用意されている。

印刷位置微調整(command-P)

左方向に0.3mm
上方向に0.1mm
      • 但し、自分の印刷環境において
  • DVD-Rとプリンタの個体差によって、印刷位置が上下左右に僅かにズレて、白いレーベル部分が目立つことがある。
  • そんな時は、プリント... >> 印刷位置で0.1mm単位の微調整ができる。
プリント...>>印刷位置
f:id:zariganitosh:20150606143502p:image:w225 f:id:zariganitosh:20150606143501p:image:w225

  • ところで、この微調整を正確に行うには、二つのことを注意しておく必要がある。
    1. セットするDVD-Rの方向を一定にすること。
    2. 微調整する時の上下の方向を間違わないこと。
DVD-Rの方向を一定にする
  • 丸いDVD-Rにも、ちゃんと方向がある。
    • 最初はこの方向に気付かなくて、何度微調整しても合わずに悩んだ。
  • 方向はレーベル外周のテキスト(ブランド名やスペックが表示されている)を基準にする。
  • DVD-Rをトレイにセットする時、レーベル外周のテキストを常に同じ位置に合わせるのだ。
    1. トレイには矢印・穴・凹凸がある。その中で自分が見やすいと思う場所を位置合わせの目印にする。
    2. 例えば、トレイの矢印を目印にして、常にレーベル外周の「CPRM」の「C」に合わせると決める。

f:id:zariganitosh:20150608110242j:image:w256

微調整する時の上下の方向
  • DVD-Rをトレイにセットする時は、トレイの矢印側が下と感じる。
    • 矢印側を下と認識すれば、トレイをプリンタへ挿入する説明図も自然に読めるので。

f:id:zariganitosh:20150608104553j:image:h225 f:id:zariganitosh:20150606103005j:image:h225

しかし...

  • 印刷結果を見て微調整する時は、トレイの矢印側を上に見る必要がある。(上記とは逆になる)
    • DVD-Rが載ったトレイは一旦奥まで吸い込まれて、矢印側から印刷を始めるので。
微調整する時の方向
f:id:zariganitosh:20150606103101j:image:h450

マニュアルとソフトウェアのダウンロード

マニュアル


レーベル印刷のアプリケーション

ノウハウ

  • 上記ページのマニュアルを見れば、レーベル印刷の手順は理解できる。
  • しかし、高い満足度で仕上げようとすると、何度か失敗を繰り返してコツを掴むことになる。
    • 今回のように人に頼まれて渡すものなら、なおさら気を使う。
  • 何を失敗して、どのようにしたら改善されたのか、そのようなコツを記録した情報がノウハウ。

ノウハウは大事!

  • ノウハウがあれば、失敗を繰り返さず、素早く、最高の仕上がりになる。
  • マニュアルには書かれていないノウハウこそ、発信する価値ある情報だ!

  • 果たして、次回以降のレーベル印刷は、無駄な失敗を繰り返さず、0.1mmのズレもなく仕上がるのか?

ノウハウに期待!

2015-06-05

今更OSXでDVDを焼いてみた

先日「このDVD(コピーガードなし・ホームビデオの類が収録されたもの)を10枚コピーして欲しい」と頼まれた。「はいはい、できますよ、お安い御用です」と引き受けたのだが、家に帰って考えてみると、最近のAppleマシンには光学式ドライブが搭載されていないことに気付いた。調べてみると、2012年のMacBook Pro Retina15(初代Retinaマシン)以降、Appleが新発売するマシンに光学式ドライブは搭載されていない。そして、過去5年以上、自分がDVDを焼いた記憶もなかった。

久々にDVDを焼こうとすると、何をどうやるか、暫し悩む。そして案の定、無駄なDVDをたくさん焼いてしまった...。今後DVD-Rを無駄にしないように、メモしておくのだ。

      • そもそもDVDって、データ容量はでかいし、物理的に焼かなきゃいけないし、時間かかる。作るのがとても面倒なのである。
      • 試しに渡されたDVDをMP4(834x480)に変換してみると70.3MB。一方、元のDVDサイズは1.25GB。
      • MP4の方が多少ぼやけた印象はあるが、それでも十分な品質に思えた。(必要ならもっとビットレートを上げてもいい)
      • 70.3MBくらいなら、Webのどこかに置いておけば、スマートフォンやタブレットでも快適に見られる。
      • そこで依頼した方に、DVDよりも映像データをファイルにして、自由にダウンロードできるようにしておくのはどうですか?と提案してみた。
      • しかし、やはり年配の方なので目に見えるもの(DVD)として手渡したい、という意向が強いようだ。DVDをコピーすること確定となった。

作業環境

DVDをコピーする手順

ポイントはたった一つ。

  • ディスクユーティリティ.appでイメージファイルを作成するときに、必ずイメージフォーマット:DVD/CDマスターを選択すること。
      • イメージファイルの拡張子が.cdrになる。
      • もし.dmg形式のままだと、DVDプレーヤーで再生できないDVDとなってしまう...。
      • OSX環境なら再生できるかもしれないが、OSX以外の環境では再生できない。
イメージファイルを作成
  • DVDを光学式ドライブに挿入する。
  • もしDVDプレーヤー.appが起動したら終了(command-Q)させる。
  • アプリケーション >> ユーティリティ >> ディスクユーティリティ.appを起動する。
  • マウントされたDVDを選択して、

f:id:zariganitosh:20150604154424p:image:w450

  • ファイル >> 新規 >> "DVD"からのディスクイメージ...を実行する。

f:id:zariganitosh:20150604154745p:image:w450

  • イメージフォーマット:DVD/CDマスターを選択して、保存ボタンを押す。

f:id:zariganitosh:20150604163213p:image:w450

ディスクを作成
  • 先ほど作成したイメージファイルDVD.cdrを選択して、ツールバーのディスクを作成ボタンを押す。

f:id:zariganitosh:20150604155945p:image:w450

  • ディスクのセット待ちになるので、

f:id:zariganitosh:20150604160459p:image:w257

  • DVD-Rを挿入すると、準備中になる。

f:id:zariganitosh:20150604160458p:image:w257

  • 準備が整ったら、ディスクを作成ボタンを押す。

f:id:zariganitosh:20150604160457p:image:w257


焼きあがった!

2015-03-30

OSX 10.10 YosemiteでWeb共有を有効にする

OSX 10.8以降、システム環境設定からWeb共有のGUI設定がなくなってしまった。しかし、なくなったのはGUI設定だけで、apache2の設定ファイルを修正すれば、以前同様Web共有が使える。そこで、簡単にWeb共有を開始できるように、以前の日記でAppleScriptにまとめておいた。

ところが、時は流れてOSX 10.10 Yosemiteでは、上記AppleScriptではWeb共有が使えなくなっていた...。

apacheのバージョン

  • 調べてみると、OSX 10.10 Yosemiteから、apacheのバージョンが2.4に変更されていた。(以前はバージョン2.2だった)
    • OSX 10.9 Mavericksまで
$ apachectl -v
Server version: Apache/2.2.26 (Unix)
Server built:   Dec 10 2013 22:09:38
    • OSX 10.10 Yosemiteから
$ apachectl -v
Server version: Apache/2.4.9 (Unix)
Server built:   Sep  9 2014 14:48:20
  • apacheの設定ファイルをバージョン2.4に対応したものに修正することで、YosemiteでもWeb共有を使えるようになるのだ。

Web共有を有効にする手順

Webサーバーを起動
  • Webサーバーを起動するだけで、Web共有は始まる。但し...
    • /Library/WebServer/Documents/をルートとするWeb共有のみ有効。
    • ユーザーごとの~/SitesをルートとするWeb共有はまだ無効。
$ sudo apachectl start

  • http://localhost
    • /Library/WebServer/Documents/index.html.enの内容が表示されている。

f:id:zariganitosh:20150330124336p:image:w450

/etc/apache2/httpd.confを修正
  • ユーザーごとのWeb共有を有効にするため、以下のコメントマークを外して、有効にしておいた。
    • userdir_moduleをロードすることを指定。
    • /etc/apache2/extra/httpd-userdir.confの設定も取り込むことを指定。

  LoadModule authz_host_module libexec/apache2/mod_authz_host.so

  LoadModule authz_core_module libexec/apache2/mod_authz_core.so

 -#LoadModule userdir_module libexec/apache2/mod_userdir.so
 +LoadModule userdir_module libexec/apache2/mod_userdir.so
  
  # User home directories
 -#Include /private/etc/apache2/extra/httpd-userdir.conf
 +Include /private/etc/apache2/extra/httpd-userdir.conf

      • −赤い行 = 修正前
      • +緑の行 = 修正後
      •  黒い行 = デフォルトの設定状態

  • ついでにPHPも有効にするには、以下のコメントマークも外して、有効にしておく。
    • php5_moduleをロードすることを指定。

 -#LoadModule php5_module libexec/apache2/libphp5.so
 +LoadModule php5_module libexec/apache2/libphp5.so

/etc/apache2/extra/httpd-userdir.confを修正
  • ユーザーごとのWeb共有を有効にするため、以下のコメントマークを外して、有効にしておいた。
    • 上記/etc/apache2/httpd.confで取り込みを指定された設定ファイルである。
    • ユーザごとの設定ファイル/etc/apache2/users/*.confの設定も取り込むことを指定。

  # Settings for user home directories
  #
  # Required module: mod_authz_core, mod_authz_host, mod_userdir
 
  #
  # UserDir: The name of the directory that is appended onto a user's home
  # directory if a ~user request is received.  Note that you must also set
  # the default access control for these directories, as in the example below.
  #
  UserDir Sites
 
  #
  # Control access to UserDir directories.  The following is an example
  # for a site where these directories are restricted to read-only.
  #
 -#Include /private/etc/apache2/users/*.conf
 +Include /private/etc/apache2/users/*.conf
  <IfModule bonjour_module>
         RegisterUserSite customized-users
  </IfModule>

      • −赤い行 = 修正前
      • +緑の行 = 修正後
      •  黒い行 = デフォルトの設定状態
~/Sites フォルダを追加
  • ユーザーごとのWeb共有の起点となる ~/Sites を追加した。(以前と同じ)
    • 上記/etc/apache2/extra/httpd-userdir.confの"UserDir Sites"という設定によって、指定されたフォルダである。
$ mkdir -p ~/Sites
~/Sites/index.htmlも追加
  • ユーザーごとのWebページの動作確認用として、「Now Web Sharing!」というテキストファイルも保存しておいた。(以前と同じ)
$ echo Now Web Sharing! > ~/Sites/index.html
/etc/apache2/users/USER_NAME.confを追加
  • ユーザーごとのWeb共有の設定である。
  • 例えば、ログインユーザー名がzariであれば、/etc/apache2/users/zari.confというパスになる。
    • 上記/etc/apache2/extra/httpd-userdir.confの"Include /private/etc/apache2/users/*.conf"という先ほど有効にした設定によって、Includeされる。
$ cat <<EOS > /etc/apache2/users/zari.conf
<Directory \"$HOME/Sites/\">
    Options Indexes MultiViews
    AllowOverride None
    Require all granted
</Directory>
EOS

# apache 2.2
Order allow,deny
Allow from all
# apache 2.4
Require all granted
Webサーバーを再起動
  • 以上の設定を反映させるため、Webサーバーを再起動する。
$ sudo apachectl restart

f:id:zariganitosh:20150330124337p:image:w450

AppleScriptにまとめる

  • 以上の仕組みをAppleScriptにまとめておくのだ。

 activate
 set res to display dialog web_sharing_msg() buttons {"キャンセル", "OFF", "ON"} cancel button 1 default button web_sharing_btn() with title "Web共有コントローラー"
 
 if res's button returned = "ON" then
   apachectl_init()
   apachectl_restart()
 end if
 
 if res's button returned = "OFF" then
   apachectl_stop()
 end if
 
 
 
 
 on apachectl_init()
   activate
   do shell script "mkdir -p ~/Sites"
   --do shell script "chmod +x ~/Sites" --ホーム直下ではデフォルト権限なので不要
   do shell script "[ -f ~/Sites/index.html ] || echo Now Web Sharing! > ~/Sites/index.html"
   
   if apache_version() starts with "2.2" then
     do shell script "f=/etc/apache2/users/`basename $HOME`.conf
 cat <<EOS > $f~
 <Directory \"$HOME/Sites/\">
     Options Indexes MultiViews
     AllowOverride None
     Order allow,deny
     Allow from all
 </Directory>
 EOS
 diff -q $f~ $f || mv $f~ $f
 rm -f $f~
 " with administrator privileges
   end if
   
   if apache_version() starts with "2.4" then
     do shell script "f=/etc/apache2/users/`basename $HOME`.conf
 cat <<EOS > $f~
 <Directory \"$HOME/Sites/\">
     Options Indexes MultiViews
     AllowOverride None
     Require all granted
 </Directory>
 EOS
 diff -q $f~ $f || mv $f~ $f
 rm -f $f~
 " with administrator privileges
   end if
   
   do shell script "f=/etc/apache2/httpd.conf
 cat $f |
 sed -E 's|#(LoadModule[ \\t]+authz_core_module[ \\t]+libexec/apache2/mod_authz_core.so)|\\1|g' |
 sed -E 's|#(LoadModule[ \\t]+authz_host_module[ \\t]+libexec/apache2/mod_authz_host.so)|\\1|g' |
 sed -E 's|#(LoadModule[ \\t]+userdir_module[ \\t]+libexec/apache2/mod_userdir.so)|\\1|g' |
 sed -E 's|#(Include[ \\t]+/private/etc/apache2/extra/httpd-userdir.conf)|\\1|g' |
 sed -E 's|#(LoadModule[ \\t]+php5_module[ \\t]+libexec/apache2/libphp5.so)|\\1|g' | # PHP enabled
 cat > $f~
 diff -q $f~ $f || mv $f~ $f
 rm -f $f~
 " with administrator privileges
   
   do shell script "f=/etc/apache2/extra/httpd-userdir.conf
 cat $f |
 sed -E 's|#(Include /private/etc/apache2/users/\\*.conf)|\\1|g' > $f~
 diff -q $f~ $f || mv $f~ $f
 rm -f $f~
 " with administrator privileges
 end apachectl_init
 
 on apachectl_restart()
   activate
   do shell script "apachectl restart" with administrator privileges
 end apachectl_restart
 
 on apachectl_stop()
   activate
   do shell script "apachectl stop" with administrator privileges
 end apachectl_stop
 
 on web_sharing_state()
   try
     do shell script "curl -s http://localhost/"
     true
   on error
     false
   end try
 end web_sharing_state
 
 on web_sharing_btn()
   if web_sharing_state() then
     3
   else
     2
   end if
 end web_sharing_btn
 
 on web_sharing_msg()
   if web_sharing_state() then
     "Web共有の状態  : ON
 " & access_url_msg() & "
 " & php_enabled_msg()
   else
     "Web共有の状態  : OFF"
   end if
 end web_sharing_msg
 
 on http_code(url_text)
   do shell script "curl -LI " & url_text & " -o /dev/null -w %{http_code}"
 end http_code
 
 on user_level_root_state()
   try
     http_code("http://localhost/~" & (system info)'s short user name) = "200"
   on error
     false
   end try
 end user_level_root_state
 
 on access_url_msg()
   if user_level_root_state() then
     "
   http://" & first_ip_address() & "/
   http://" & first_ip_address() & "/~" & (system info)'s short user name & "/
 "
   else
     "
   http://" & first_ip_address() & "/
 "
   end if
 end access_url_msg
 
 on php_enabled()
   try
     set status_code to do shell script "grep -E '^LoadModule[ \\t]+php5_module[ \\t]+libexec/apache2/libphp5.so$' /etc/apache2/httpd.conf"
     true
   on error
     false
   end try
 end php_enabled
 
 on php_enabled_msg()
   if php_enabled() then
     "  <?php ... ?> 有効"
   else
     "  <?php ... ?> 無効"
   end if
 end php_enabled_msg
 
 on apache_version()
   do shell script "apachectl -v | awk '/version/{print $3}' | sed -E 's/[^0-9.]+//'"
 end apache_version
 
 --優先順位の高いIPアドレスを取得
 on first_ip_address()
   do shell script "ipconfig getifaddr `netstat -rn -f inet | awk '/^default/{print $6;exit}'`"
 end first_ip_address


  • 上記スクリプトを実行すると、以下のように表示され、Web共有のON・OFFと状態の確認ができるのだ。

f:id:zariganitosh:20150330124339p:image:w450

f:id:zariganitosh:20150330124338p:image:w450

参考ページ

以下のページがたいへん参考になりました。感謝です!

2015-03-29

優先順位の高いローカルIPアドレスを取得するコマンド

iMacのIPアドレスを確認したい。そんなの簡単、簡単。システム環境設定 >> ネットワークで確認すればいい。

上段のネットワークサービスほど優先順位が高くなる。よって、現在のIPアドレスは特に指定しない限り、10.0.1.20が利用されることになる。

f:id:zariganitosh:20150327175025p:image:w450

このようにGUIでは何の苦労もなく確認できるのだけど、コマンドを使って確認しようとすると、途端に深い悩みとなった...。


ipconfig

  • ipconfigにデバイス名(en0、en1など)を指定すると、そのデバイスに割り当てられたIPアドレスを取得できた。
$ ipconfig getifaddr en0
10.0.1.20

$ ipconfig getifaddr en1
10.0.1.102

しかし...

  • デバイス名を指定する必要があり、すべてを網羅する自信がない。
  • また、どちらの優先順位が高いのかは分からない...。

ifconfig

  • ifconfigなら、すべてのデバイスの接続状況が一覧できる。
$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
	options=3<RXCSUM,TXCSUM>
	inet6 ::1 prefixlen 128 
	inet 127.0.0.1 netmask 0xff000000 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=1<PERFORMNUD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=10b<RXCSUM,TXCSUM,VLAN_HWTAGGING,AV>
	ether xx:xx:xx:xx:xx:xx 
	inet6 xxxx::xxxx:xxxx:xxxx:xxxx%en0 prefixlen 64 scopeid 0x4 
	inet 10.0.1.20 netmask 0xffffff00 broadcast 10.0.1.255
	nd6 options=1<PERFORMNUD>
	media: autoselect (1000baseT <full-duplex,flow-control>)
	status: active
en1: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether xx:xx:xx:xx:xx:xx
	inet6 xxxx::xxxx:xxxx:xxxx:xxxx%en1 prefixlen 64 scopeid 0x5 
	inet 10.0.1.102 netmask 0xffffff00 broadcast 10.0.1.255
	nd6 options=1<PERFORMNUD>
	media: autoselect
	status: active
...中略...
  • リスト中の「inet 」の項目がIPアドレス(IPv4)らしいので、抜き出してみた。
$ ifconfig|grep 'inet '
	inet 127.0.0.1 netmask 0xff000000 
	inet 10.0.1.20 netmask 0xffffff00 broadcast 10.0.1.255
	inet 10.0.1.102 netmask 0xffffff00 broadcast 10.0.1.255
  • awk使って、IPアドレスのみ取り出してみた。
$ ifconfig|awk '/inet /{print $2}'
127.0.0.1
10.0.1.20
10.0.1.102

しかし...

  • どちらの優先順位が高いのかは分からない...という問題は依然残る...。

AppleScript

  • AppleScriptにはsystem infoがあり、その中にIPv4 addressというプロパティがあった。
  • そして、osascriptを使えば、コマンドラインからでもAppleScriptを実行できる。
$ osascript -e 'IPv4 address of (system info)'
10.0.1.20

しかし...

  • Wi-FiとEthernetの両方を接続した時、Wi-Fiを優先しても、常にEthernetのIPアドレスが表示されてしまう...。なぜだろう?

いろいろな方法

  • 調べてみると、多くの方がコマンドでローカルIPアドレスを取得することに苦労しているようだ。
  • こうなったら上記ページで紹介されている方法を片っ端からすべて試してみる。
  • そしてついに「優先順位の高いローカルIPアドレス」を取得することができた!
$ python -c "import socket;print([(s.connect( ('8.8.8.8', 80) ), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)[0][1])"
10.0.1.20
  • OSX標準で、余分なライブラリをインストールせずに、優先順位の高いローカルIPアドレスを取得する方法は、これ一つだった。

しかし...

  • 8.8.8.8という外部のDNSサーバーへの接続に依存しているところに不満が残る。
    • 8.8.8.8を指定するなら、必ずインターネットに接続している必要がある。
  • 8.8.8.8の部分はLAN内のDNSサーバー10.0.1.1などを指定してもOKなのだけど、
    • 192.168.x.xとか、172.16.x.xなどもあり得る。環境に合わせて変更するのは面倒だ。
  • 自分自身で設定したネットワーク設定なのだから、外部に頼らず、自己解決したい気がする。

networksetup

  • OSXのネットワーク環境を設定するコマンドとして、networksetupが用意されている。
  • networksetupを使えば、システム環境設定 >> ネットワークと同様の設定ができるらしい。

  • 優先度順にネットワークサービス名のリストが表示された!
$ networksetup -listallnetworkservices
An asterisk (*) denotes that a network service is disabled.
Wi-Fi
Ethernet
Thunderbolt Ethernet 2
Thunderbolt ブリッジ

  • Wi-FiのIPアドレスを取得できた!
$ networksetup -getinfo Wi-Fi
Manually Using DHCP Router Configuration
IP address: 10.0.1.102
Subnet mask: 255.255.255.0
Router: 10.0.1.1
IPv6: Automatic
IPv6 IP address: none
IPv6 Router: none
Wi-Fi ID: xx:xx:xx:xx:xx:xx

  • でもWi-Fiが切であっても、IPアドレスが表示されてしまう...。(固定IPアドレスを指定している場合)
$ networksetup -getinfo Wi-Fi
Manually Using DHCP Router Configuration
IP address: 10.0.1.102
IPv6: Automatic
IPv6 IP address: none
IPv6 Router: none
Wi-Fi ID: xx:xx:xx:xx:xx:xx

  • Subnet maskRouterが表示されていなければ、オフラインと考えてよいのだろうか?
  • ならば、オフラインを除外してネットワークサービスの順番にIPアドレスを調べればいいのだ!
$ networksetup -listallnetworkservices|sed '1d'|while read s; do networksetup -getinfo "$s"|grep -q '^Router: ' && networksetup -getinfo "$s"|awk -F': ' '/^IP address: /{print $2}'; done|head -1
10.0.1.20
  • 上記ワンライナーをもう少し分かりやすく書き直せば、以下のようなシェルスクリプトとなる。
networksetup -listallnetworkservices | sed '1d' | while read s
do 
  if networksetup -getinfo "$s" | grep -q '^Router: '; then
    networksetup -getinfo "$s" | awk -F': ' '/^IP address: /{print $2}'
  fi
done | head -1

しかし...

  • 手入力でTCP/IPを設定した場合は、オフラインであってもSubnet maskRouterが表示されてしまった...。
  • 結局、networksetup -getinfoはネットワークサービスのTCP/IPに設定された情報を表示しているに過ぎない。
    • DHCPを利用した場合はオフラインではルーターは未設定となるが、
    • 手入力ではオフラインでも入力済みのルーターアドレスが表示される。

f:id:zariganitosh:20150328173001p:image:w450

  • 上記のように設定しておくと、オフラインでもnetworksetup -getinfo Wi-Fiは以下の情報を出力してしまう...。
$ networksetup -getinfo Wi-Fi
Manual Configuration
IP address: 10.0.1.102
Subnet mask: 255.255.255.0
Router: 10.0.1.1
IPv6: Automatic
IPv6 IP address: none
IPv6 Router: none
Wi-Fi ID: b8:09:8a:b9:c8:5d

ifconfig+networksetup

  • こうなったら、ifconfigとnetworksetupの合わせ技でやってみる。
    • ifconfigでオンラインのIPアドレスを確認して、
    • networksetupでネットワークサービスの優先順位を確認するのだ。
$ networksetup -listallnetworkservices|sed '1d'|while read s; do networksetup -getinfo "$s"|grep -q '^IP address: ' && ifconfig|awk '/inet /{print $2}'|grep `networksetup -getinfo "$s"|awk -F': ' '/^IP address: /{print $2}'`; done|head -1
10.0.1.20
  • 上記ワンライナーをもう少し分かりやすく書き直せば、以下のようなシェルスクリプトとなる。
networksetup -listallnetworkservices | sed '1d' | while read s
do 
  if networksetup -getinfo "$s" | grep -q '^IP address: '; then
    i=`networksetup -getinfo "$s" | awk -F': ' '/^IP address: /{print $2}'`
    ifconfig | awk '/inet /{print $2}' | grep "$i"
  fi
done | head -1

できた!


ipconfig+netstat

  • コメントで教えて頂いた方法が素晴らしい!(nsbyさんに感謝!)
  • きっと経験豊富なネットワーク管理者はこの方法を使っているはず。
$ ipconfig getifaddr `netstat -rn -f inet | awk '/^default/{print $6;exit}'`
10.0.1.20
  • networksetupのようなOSXに依存するコマンドも使わないので、多くのUNIX環境で利用できるはず。

仕組みとしては...

  • 例えばipconfig getifaddr en0を実行すれば、en0に割り当てられたIPv4アドレスが求められる。
  • ならば、en0の部分に、優先順位の高いネットワーク インターフェース名を指定すればいいのだ。
  • それを求めるのが`netstat -rn -f inet | awk '/^default/{print $6;exit}'`の部分。
    • netstat -rn -f inetコマンドでルーティングテーブルを表示している。
      • rオプションは、ルーティングテーブルを表示する指定。
      • nオプションは、ホストやユーザーの名前解決を行わず数字のまま出力する指定。(たぶんコマンドの動作が軽くなる)
      • -f inetオプションは、IPv4のルーティングテーブルのみに限定する指定。
    • 上記出力からawk '/^default/{print $6;exit}'コマンドで、デフォルトのNetifのみ取り出している。
      • exitによって、最初の(優先順位の高い)defaultを見つけたら、その後の処理を中断している。

  • シンプルな動作の組合せなので、このワンライナーを丸暗記しなくても覚えられそう。
  • (忘れやすいので)できる限りオプション指定しないで入力してみると、以下でもOKだった。
ipconfig getifaddr `netstat -r | awk '/^default/{print $6}'`
  • xargsを利用して、以下のように表現してもOKだった。
netstat -r | awk '/^default/{print $6}' | xargs ipconfig getifaddr

2014-11-13

Safariのレンダリングの失敗対策

最近、たまにOSX10.10 Yosemiteを触っている(実験用の環境)のだけど、Safariを使っていてページの一部が完全にレンダリングされない状態が気に障る。

f:id:zariganitosh:20141114100840p:image:w450

f:id:zariganitosh:20141114100837p:image:w450

  • 情報非開示にしたつもりはない(そんな設定ない!)のに、ページ左上の部分が黒塗りになる。
  • タブを切り替えていると頻繁に発生する気がする。
    • 10タブ切り替えで1レンダリング失敗くらいな割合。
  • スクロールしても治らず、クリックしても治らず...。
  • 素早くその部分が見たい時は、今まで再読み込みしていたのだけど、
  • 偶然にも、もっと素早く回復する方法があった。

command / /(commandキー押しながら、スラッシュ/2回押し)


  • 何が起こるかというと、Safariのステータスバーの表示・非表示を素早く切り替えている。
    • ステータスバー=ウィンドウ最下部に表示される情報表示のバー。
  • そうするとウィンドウ全体が再描画されるらしく、黒塗の部分は一瞬にして再描画された!
  • ステータスバーに限らず、「表示」メニューのどれかを実行すれば、同様に再描画された。
  • よって、command-shift-B-B(お気に入りバーの表示・非表示)でも、command-shift-L-L(サイドバーの表示・非表示)等でも、OK。
  • ショートカットのシンプルさと、(USキーボード配列だと、右手のみで素早く押せる)
  • レンダリングする時の負荷が必要最小であると感じたのが、command / /だった。
  • すべての環境で同じようなレンダリングの失敗が発生するとは限らないが、
  • 少なくとも、自分のMacBook Pro Retina15(2012 mid)においては発生している。
  • Marvericksの時もごく稀に発生していたけど、(年に数回くらい、気にならないレベル)
  • Yosemiteになって、ブログに書きたくなるくらいの我慢ならないレベルとなった...。

早くアップデートで改善して欲しい...。(はかない期待)


  • 最初に駄目出しをしてしまったけど、Yosemite Safari8.0の使い勝手は好き。
  • タブがスクロールするようになった!
    • タブを開きまくる自分としては、表示しきれなくなった末尾付近のタブのタイトルが見れなくて不便を感じていた。
    • Yosemite Safariなら、タブはスクロールするし、末尾付近のタブをクリックすれば、その付近のタブのタイトルが素早く表示された。
  • ピンチ イン(親指と人差し指で挟む)操作でタブの一覧が表示された!
    • ホスト名が同じサイトは、グループ化された。
    • Safari内ミッションコントロールと言った感じ。
    • iOS端末などで開いているページも一覧できた。

f:id:zariganitosh:20141114110403p:image:w450

f:id:zariganitosh:20141114110401p:image:w450

2014-10-28

起動時の「接続に失敗しました」警告対策

OSX 10.6.8のMacBookを起動した時に、いつの頃からか「接続に失敗しました」という警告が出るようになってしまった。

f:id:zariganitosh:20141016165002p:image

接続に失敗しました

サーバ"MacBook-Pro-Retina15(3)"が存在しないか、現在利用できません。

サーバーの名前またはIPアドレス、およびネットワーク接続を確認してから、もう一度やり直してください。

まったく身に覚えがない...。長らく、どうして起動時にMacBook-Pro-Retina15(3)に接続しようとするのか、原因不明のままだった。

  • 普段はモニタを閉じてスリープするだけで、再起動することがほとんどない、ということがこの問題の放置に拍車をかけた。
  • それに、警告されるだけで、OKボタンを押すと問題なく起動が完了して、正常に使えたので。
  • 警告される煩わしさ、ボタンを押す面倒臭さ、原因不明の気持ち悪さ、を我慢して使い続けてしまった。

共有のコンピュータ名に数字が付加されて増えていく怪現象

  • (3)という数字が付加していることには、以下のような経緯がある。
  • もう一台のMacBook Proは、共有のコンピュータ名を「MacBook-Pro-Retina15」としているのだけど、
  • 何らかの原因でネットワーク上で名前がダブってしまうことがあるらしい。
  • OSXは、ネットワーク上で名前がダブっていると判断すると、自分の名前に"(n)"を付加する仕様のようだ。
    • ファイル名がダブっている場合も、数字が付加される。その仕組みに似ている。
  • nは数字である。1から始まり、ダブっていると判断される度に+1ずつ加算され、増えていく。
  • そのまま放っておくと、MacBook-Pro-Retina15(12)なんて名前になっていることもあった。
  • ある時、コンピュータ名に数字が付加されてどんどん増えていく問題は、無線LANが原因と分かった。
  • 有線LANで接続している場合は、いつまでたっても「MacBook-Pro-Retina15」が維持され、数字が付加されることはないのだ。
  • そこで、現在はほとんど有線LANで接続して使うようになった。
  • コンピュータ名も手入力で「MacBook-Pro-Retina15」と入力し直した。

想像と試行錯誤

  • 「サーバ"MacBook-Pro-Retina15(3)"が存在しない」と警告するMacBookは、MacBook Pro Retina15が無線LANで接続している時に、何らかの共有をしたのだと思う。
  • "MacBook-Pro-Retina15(3)"が存在しなくなった現在も、なぜか起動する時に接続しようとしている。
  • しかし、MacBookの設定を見直してみたが、接続するような設定はどこにも残っていない...。
    • どこかにMacBook-Pro-Retina15(3)のエイリアスがあるのではないかと探したが、どこにもなかった...。
    • そもそも、たとえエイリアスが残っていても、そのエイリアスを開こうとしない限り、接続することはないはず。
    • Finderのサーバへ接続...が怪しいと思って、そこに残っている履歴もすべて削除してみたが、状況変わらず...。
    • /Library/StartupItems/やlaunchd.plistの設定も確認したけど、原因らしきものは見当たらない...。
    • 残るはログイン項目か?と思い確認してみたが、サーバに接続するような設定は見当たらない...。

もはやここまでか?と諦めかけた時、stringsコマンドを使った検索技を思い出した。

stringsコマンドで設定ファイルから文字列を探す

  • stringsコマンドは、ファイル中に存在する文字列を取り出してくれるコマンド。
  • バイナリファイルや実行ファイルであっても、そこに含まれる文字列を探して出力してくれる。
  • GUIにはない未知の設定項目などを探す時にも、強力な道具となるコマンドだ。
  • "MacBook-Pro-Retina15(3)"に接続しようとするならば、どこかに接続しようとさせる設定ファイルが残っているはずである。
  • 当然、その設定ファイルには"MacBook-Pro-Retina15(3)"という文字列が含まれているのではないかと予想した。
  • 設定ファイルと言えば、~/Library/Preferences/以下に存在する.plistが怪しい。
  • stringsコマンドで片っ端から.plistを検索して、"MacBook-Pro-Retina15(3)"を含む設定ファイルを探してみようと決意した。

~/Library/Preferences/から"MacBook-Pro-Retina15"を検索するワンライナー

  • そこにファイルは400項目近くあるので、とても手作業ではやってられない。
  • 以下のようなシェルスクリプトを書いて、実行してみた。
for f in ~/Library/Preferences/*; do if strings $f 2>/dev/null|grep 'MacBook-Pro-Retina15'; then echo ======== $f; fi; done

  • すると、MacBook-Pro-Retina15を含む設定ファイルのリストが表示された!
...中略...
 afp://bebe-MacBook-Pro-Retina15(3)._afpovertcp._tcp.local
 ======== /Users/zari/Library/Preferences/com.apple.loginitems.plist
...中略...
 \f0\fs24 \cf0 bebe-MacBook-Pro-Retina15}
 ======== /Users/zari/Library/Preferences/com.aynimac.CotEditor.plist
...中略...
  • 暫し眺めていて、そして気付いた。

限りなくcom.apple.loginitems.plistが怪しい!

  • com.apple.loginitems.plistは、システム環境設定 >> アカウント >> ログイン項目の設定を保存するファイルである。
  • システム環境設定を目視して確認する限り、MacBook-Pro-Retina15を共有するような設定は見当たらないのだけど、
  • 未知のログイン項目のどこかに、afp://bebe-MacBook-Pro-Retina15(3)._afpovertcp._tcp.localを共有しようとする設定が残っているのかもしれない。
  • 疑いの目線で再びログイン項目を確認してみると、種類が「不明」となっている項目が気になってきた。

f:id:zariganitosh:20141017101828p:image:w450

  • ログイン項目には、全部で5項目の「不明」があった。
  • 「不明」の項目は、AppleScriptで作ったアプリケーションやシェルスクリプトが登録されているみたい。
  • ひとつ一つ中身を確認するのは面倒なので、5項目すべて削除してみた。
  • 再起動してみる...
  • すると「接続に失敗しました」は表示されずに起動が完了した!

直った!

原因の想像

直接的な原因がわからずに解決してしまったので、考えられる2つの原因をメモしておく。

  • ログイン項目に登録されていた「不明」の5項目のどれかが悪さをしていた。
    • 削除したことで、MacBook-Pro-Retina15(3)を共有しなくなった。
  • GUI上には表示されない未知の設定項目がcom.apple.loginitems.plist残ってしまっていた。
    • ログイン項目を削除あるいは追加したことで、GUI上見える項目のみに設定がリセットされた。

  • 再度、設定ファイルからMacBook-Pro-Retina15を検索してみると、com.apple.loginitems.plistは表示されなくなった。
for f in ~/Library/Preferences/*; do if strings $f 2>/dev/null|grep 'MacBook-Pro-Retina15'; then echo ======== $f; fi; done

まとめ

試してみる価値のある手順

  • ログイン項目に何かを追加して、削除してみる。

  • 種類が不明のログイン項目を一つずつ削除してみる。
    • 削除する前には、バックアップを忘れずに。
    • ログイン項目のスクリーンショットも撮影しておく。

  • 以下のシェルスクリプトを使って、設定ファイルをキーワード検索してみる。
    • 'キーワード'の部分に、警告文中の固有のテキストを入力して、実行するのだ。
    • 出力された設定ファイルが怪しい!
for f in ~/Library/Preferences/*; do if strings $f 2>/dev/null|grep 'キーワード'; then echo ======== $f; fi; done

2014-10-10

AppleUSBEthernetHost.kextは正しくインストールされていない対策

症状

f:id:zariganitosh:20141010074929p:image:w450

機能拡張を使用できません

機能拡張"/System/Library/Extensions/AppleUSBEthernetHost.kext"は正しくインストールされていないため使用できません。再インストールするか、製品の製造元にアップデートについて問い合わせてください。

対策

最新のiTunesをダウンロードして、再インストールしてみる。

変化を観察

再インストール前

f:id:zariganitosh:20141008152143p:image:w450

更新日: 2013年7月24日 15:05
再インストール後

f:id:zariganitosh:20141008152140p:image:w450

更新日: 2014年7月30日 5:48

再インストール後、"/System/Library/Extensions/AppleUSBEthernetHost.kext"が新しいものに置き換わった!


  • うまくインストールできない場合は、"/System/Library/Extensions/AppleUSBEthernetHost.kext"をゴミ箱に捨てて(command-delete)みる。
  • システムファイルを変更するので管理者権限が必要。

f:id:zariganitosh:20141011073750p:image:w450

f:id:zariganitosh:20141011073748p:image:w450

  • その後iTunesをインストールすると正常に完了した。
  • インストール後はマシンを再起動するのを忘れずに。

2014-10-09

bashのアップデート


上記アップデート前

$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
vulnerable
this is a test
""
  • 環境変数xに設定した'() { :;}; echo vulnerable'のecho vulnerableの部分が実行されているのだ。
  • そして、設定したはずの環境変数xは空っぽ...。

上記アップデート後

$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
this is a test
"() { :;}; echo vulnerable"

直った!

Snow Leopardをどうするか

  • 残念ながら、Snow Leopardのbashのアップデートは提供されていない...。
  • そうか、影響しないのかと試してみると、思い切り影響している!
$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
vulnerable
this is a test
""

  • という訳で、とりあえず一番バージョンの近いLion用のbashアップデートをダウンロードしてみた。
  • 実行してみると、「このアップデートには10.7が必要です」と警告されて、インストールできない...。

  • もはや、Snow Leopardはサポート対象外になったのか...。
  • 諦めようと思ったのだけど、そう言えばpkgutilなんてコマンドがあったような気がした。
  • pkgutilと入力して、実行してみると、ヘルプが表示された!
$ pkgutil
Usage: pkgutil [OPTIONS] [COMMANDS] ...

Options:
  --help                 Show this usage guide
  --verbose, -v          Show contextual information and format for easy reading
  --force, -f            Perform all operations without asking for confirmation
  --volume PATH          Perform all operations on the specified volume
  --edit-pkg PKGID       Adjust properties of package PKGID using --learn PATH
  --only-files           List only files (not directories) in --files listing
  --only-dirs            List only directories (not files) in --files listing
  --regexp               Try all PKGID arguments as regular expressions

Database Commands:
  --pkgutil-version      Show pkgutil version.
  --pkgs, --packages     List all currently installed package IDs on --volume
  --pkgs-plist           List all package IDs on --volume in plist format
  --pkgs=REGEXP          List package IDs on --volume that match REGEXP
  --groups               List all GROUPIDs on --volume
  --groups-plist         List all GROUPIDs on --volume in plist format
  --group-pkgs GROUPID   List all PKGIDs in GROUPID
  --files PKGID          List files installed by the specified package
  --lsbom PKGID          List files in the same format as 'lsbom -s'
  --pkg-groups PKGID     List all GROUPIDs that PKGID is a member of
  --export-plist PKGID   Print all info about PKGID in plist format
  --verify PKGID         Verify file permissions of the specified package
  --repair PKGID         Repair file permissions of the specified package
  --pkg-info PKGID       Show metadata about PKGID
  --pkg-info-plist PKGID Show metadata about PKGID in plist format
  --file-info PATH       Show metadata known about PATH
  --file-info-plist PATH Show metadata known about PATH in plist format
  --forget PKGID         Discard receipt data for the specified package
  --unlink PKGID         Delete the files installed by the specified package
  --learn PATH           Update --edit-pkg PKGID with actual metadata from PATH

File Commands:
  --expand PKG DIR       Expand the flat package PKG to DIR
  --flatten DIR PKG      Flatten the files at DIR as PKG
  --bom PATH             Extract any Bom files from the pkg at PATH into /tmp
  --payload-files PATH   List the paths archived within the (m)pkg at PATH

  • ざっと眺めてみると、--expand PKG DIRが使えそうな、そんな気がする。
$ cd ~/Desktop
$ pkgutil --expand "/Volumes/OS X bash update/BashUpdateLion.pkg" bash_upate

  • すると、デスクトップにbash_upateが出現し、その中に3つのファイルが見える。
$ ls
BashUpdateLion.pkg/    Distribution*    Resources/

  • しばらくすると、Distributionは実行ファイルなのだけど、その実体はxmlに包まれたスクリプトであることに気付いた。
  • そして、その中に見える10.7の文字は、インストーラーがチェックしているOSXのバージョン番号であると予想できる。
  • 10.7がLion以降をチェックするのなら、そこをすべて10.6に置き換えてしまうとSnow Leopardでもインストールできるのではないか?
  • 至極自然な予想であり、それは確信となりつつあり、そう思い始めたらもう止められない。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<installer-gui-script minSpecVersion="1">
    <options hostArchitectures="i386" customize="never"/>
    <title>SU_TITLE</title>
    <script>
</script>
    <volume-check script="VolumeCheck()"/>
    <installation-check script="InstallationCheck()"/>
    <script>
function InstallationCheck(prefix) {
	if (system.compareVersions(system.version.ProductVersion, '10.7') &lt; 0 || system.compareVersions(system.version.ProductVersion, '10.8') >= 0) {
		my.result.message = system.localizedStringWithFormat('ERROR_0', '10.7');
		my.result.type = 'Fatal';
		return false;
	}
	return true;
}
function VolumeCheck(prefix) {
	if (system.env.OS_INSTALL == 1) return true;
	var hasOS = system.files.fileExistsAtPath(my.target.mountpoint + "/System/Library/CoreServices/SystemVersion.plist");
	if (!hasOS || system.compareVersions(my.target.systemVersion.ProductVersion, '10.7') &lt; 0 || system.compareVersions(my.target.systemVersion.ProductVersion, '10.8') >= 0) {
		my.result.message = system.localizedStringWithFormat('ERROR_0', '10.7');
		my.result.type = 'Fatal';
		return false;
	}
	if (!hasOS || system.compareVersions(my.target.systemVersion.ProductVersion, '10.7.5') &lt; 0) {
		my.result.message = system.localizedStringWithFormat('ERROR_2', '10.7.5');
		my.result.type = 'Fatal';
		return false;
	}
	return true;
}
</script>
    <license file="License.rtf"/>
    <readme file="SUDescription.html"/>
    <choices-outline>
        <line choice="manual"/>
    </choices-outline>
    <choice id="manual" title="SU_TITLE">
        <pkg-ref id="BashUpdateLion" auth="Root">#BashUpdateLion.pkg</pkg-ref>
    </choice>

	<pkg-ref id='BashUpdateLion' installKBytes='3906' version='1.0.1.1306847324'/>

	<pkg-ref id='BashUpdateLion' installKBytes='3906' version='1.0.1.1306847324'/>
</installer-gui-script>
  • テキストエディタで開いて、10.7を10.6に一括置き換え。
    • ちなみに、10.7.5の部分は10.6.5となった。

  • この修正を反映して、元のpkgファイルに戻すことができれば、インストールできるかもしれない。
  • pkgutilのヘルプを見ると、--expand PKG DIRの下には、--flatten DIR PKGがある。
  • 引数の部分がPKG DIRの逆順 DIR PKGという並びになっていることから、pkgファイルに復元できそうな予感がする。
$ pkgutil --flatten bash_update BashUpdate.pkg
  • すると、見事にデスクトップにBashUpdate.pkgが出現した。

  • 念のためOSX環境全体をバックアップしてから、ダブルクリックで実行してみると...

見事にインストーラーが起動して、正常にインストールできてしまった!(気がする)

  • 果たして、Snow Leopardのbashも直ったのか?
$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
this is a test
"() { :;}; echo vulnerable"

直った!

      • 但し、Snow Leopard用ではないので、どこかに何らかの問題が出るかもしれない。

2014-10-08

ログインシェルを変更する方法

作業環境

手順

  • システム環境設定 >> ユーザとグループを開く。

f:id:zariganitosh:20141008112957p:image:w450


  • 左下の鍵アイコンをクリックして、ロックを解除する。

f:id:zariganitosh:20141008114040p:image:w450


  • ユーザを選択して二本指タップして、詳細オプションを開く。
    • 二本指タップ = 右クリック = control-クリック

f:id:zariganitosh:20141008113935p:image:w450


  • ログインシェルを選択する。リストにない場合はパスを手入力する。OKボタンをクリックして完了。

f:id:zariganitosh:20141008121015p:image:w450

  • ターミナルを再起動して、$SHELLが指定したパスになっていればOK。
$ echo $SHELL
/usr/local/bin/bash

あるいは...

$ dscl localhost -read Local/Default/Users/$USER UserShell
UserShell: /usr/local/bin/bash

コマンド操作不要

上記のようにシステム環境設定から設定すれば、以下のコマンドラインでの操作は不要である。

  • /etc/shellsに新しいシェルのパスを追加して、
  • chpassコマンドでそのシェルパスを指定とか。
$ sudo sh -c "echo /usr/local/bin/bash >> /etc/shells"
$ chpass -s /usr/local/bin/bash

ターミナル起動時に開くシェル

  • ターミナルでタブやウィンドウを開く時に起動するシェルを設定できる。
    • 通常はログインシェルが起動する設定になっているのだけど、
    • ターミナル >> 環境設定 >> 起動 >> 開くシェル: コマンド(完全パス)を設定しておくことで、ログインシェル以外も指定できる。

但し、ログインシェルと、ターミナルでコマンド指定して起動したシェルは、若干の違いがある。


  • sshでリモートログインした時は、必ずログインシェルが起動する。
  • suでユーザーを切り替えた時も、必ずログインシェルが起動する。

f:id:zariganitosh:20141008141509p:image:w450

  • 上記設定でターミナルのタブやウィンドウを閉じる時、
    • ログインシェルは、起動していても確認なしで閉じる設定になっている。
    • ターミナルが開くシェルは、確認なしで閉じる設定に追加しておかないと、閉じる前に確認される。