コンテンツにスキップ

Recent Posts

Vagrant provisioning の謎

Vagrant で立てた CentOS の仮想環境にちょっとした環境構築をしようと、provision ファイルを作って vagrant provision で実行しようとしたところ RVM のインストールから先が上手くいかなかった。

vagrant provision に関しては 過去のエントリ に記載があります)

provision ファイルの該当箇所は以下

# ruby and rails
curl -L https://get.rvm.io | bash -s
source ~/.profile

rvm requirements
rvm install 2.0.0 --with-openssl-dir=$HOME/.rvm/usr

上記コマンドのうち、

curl -L https://get.rvm.io | bash -s

だけが実行できているが、このコマンドの結果も意図したものとなっていない。 それ以降のコマンドは失敗する。

まだ原因は良くわかっていない。

  • RVM のインストール自体はできている
  • どのユーザー(vagrant? root?)で実行されているのか分からない
  • vagrant ユーザーに対しては rvm コマンドの path が通っているが、root ユーザーには通っていない
  • provision 実行のログ的には root で実行しているように見える
  • vagrant ssh して手動でコマンドを実行すると意図した結果になる

sed コマンドで置換

ファイルの中身を置換する必要があったので sed コマンドを使った。

使うオプション

今回使うのは

  • 変換処理の条件式を指定するための e オプション
  • 変換してそのままファイルを上書きする i オプション

やってみる

今回はこんな感じ

sed -ie '条件式' ファイル名
$ cat test
testtesttest

$ sed -ie 's/test/hoge/g' test

$ cat test
hogehogehoge

$ ls
test teste

指定したファイルは条件に沿って置換されているが、オリジナルの内容を持ったファイルも生成されている

オリジナルの内容を持ったファイルは使う sed コマンド(OS)によって元のファイル名に 'e' が付いたり '-e' が付いたりする

find コマンドの使い方

いつまでも find コマンドの使い方を覚えられないアホなのでメモしておく。。。

基本的に

find [探すディレクトリ] -name 'ファイルの条件'

これだけは覚えとけ、と。

たまには

find . -name '*.swp' -ok rm {} \;

見つけたファイルをそのまま次のコマンドに受け渡す -ok オプションもたまには使えるかも知れない。

CPAN モジュールのリリース

上司にお膳立てされ、後輩にお尻を叩かれ、やっとのことで CPAN モジュールをリリースしました。

前回のエントリに続き、リリースの手順を記します。

モジュールの作成

ここがコアの部分ですが、内容は作るモジュールに依るので割愛。編集すべきは以下のファイルです。

  • lib/ 配下のプログラム
  • t/ 配下のテストプラグラム
  • cpanfile

cpanfile の作成は scan-prereqs-cpanfile を使うと便利です。

このコマンドは App::scan_prereqs_cpanfile モジュールで提供されています。

cpanm App::scan_prereqs_cpanfile
scan-prereqs-cpanfile > cpanfile

テスト

モジュールの作成ができたら test を実行しますが、このとき minil test コマンドを使うと Changes や META.json、README.md が自動で編集されます。

$ minil test
Creating working directory: /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7
cp Build.PL /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/Build.PL
cp Changes /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/Changes
cp LICENSE /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/LICENSE
cp META.json /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/META.json
cp README.md /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/README.md
cp cpanfile /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/cpanfile
cp lib/JSON/MergePatch.pm /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/lib/JSON/MergePatch.pm
cp minil.toml /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/minil.toml
cp t/00_compile.t /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7/t/00_compile.t
Building /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7
Retrieving meta data from lib/JSON/MergePatch.pm.
Name: JSON::MergePatch
Abstract: It's new $module
Version: 0.01
fatal: bad default revision 'HEAD'
Writing MANIFEST file
Writing release tests: xt/minilla/minimum_version.t
Writing release tests: xt/minilla/cpan_meta.t
Writing release tests: xt/minilla/pod.t
Writing release tests: xt/minilla/spelling.t
Writing release tests: xt/minilla/permissions.t
[5DuYQ9x7] $ perl -I. Build.PL
Creating new 'Build' script for 'JSON-MergePatch' version '0.01'
[5DuYQ9x7] $ perl -I. Build build
cp lib/JSON/MergePatch.pm blib/lib/JSON/MergePatch.pm
t/00_compile.t .. ok   
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.01 usr  0.01 sys +  0.03 cusr  0.01 csys =  0.06 CPU)
Result: PASS
Removing /user/home_directory/git/cpan/JSON-MergePatch/.build/5DuYQ9x7

リリース

テストが通ったらいよいよリリースします。

CPAN へのリリースには PAUSE ID が必要です。取得方法はこちら

リリースには minil release コマンドを使います。

$ minil release

Release engineering requires Version::Next, but it is not available. Please install Version::Next using your preferred CPAN client at ...

Version::Next がないと怒られたので入れて再度実行。

$ cpanm Version::Next
...

$ minil release

Release engineering requires CPAN::Uploader, but it is not available. Please install CPAN::Uploader using your preferred CPAN client at ...

今度は CPAN::Uploader がないと怒られたので入れて再度実行。

$ cpanm CPAN::Uploader
...

$ minil release

Retrieving meta data from lib/JSON/MergePatch.pm.
Name: JSON::MergePatch
Abstract: JSON Merge Patch implementation
Version: 0.01
Next Release? [0.01] 
Name: JSON::MergePatch
Abstract: JSON Merge Patch implementation
Version: 0.01
...
All tests successful.
Files=8, Tests=67,  0 wallclock secs ( 0.04 usr  0.03 sys +  0.18 cusr  0.04 csys =  0.29 CPU)
Result: PASS
Wrote JSON-MergePatch-0.01.tar.gz
Upload to CPAN
Release to CPAN ? [y/n]   y
missing user argument at

リリースバージョンの確認と、 CPAN にリリースするかの確認に答えていざリリース、と思いきや

missing user argument at

と怒られました。

どうやら ~/.pause ファイルに PAUSE のユーザー情報を記載する必要があるようです。

$ vim ~/.pause
$ cat ~/.pause
user SOJIRO
password your_password

再度実行

$ minil release

Retrieving meta data from lib/JSON/MergePatch.pm.
Name: JSON::MergePatch
Abstract: JSON Merge Patch implementation
Version: 0.01
Next Release? [0.01] 
Name: JSON::MergePatch
Abstract: JSON Merge Patch implementation
Version: 0.01
...
All tests successful.
Files=8, Tests=67,  0 wallclock secs ( 0.04 usr  0.03 sys +  0.18 cusr  0.05 csys =  0.30 CPU)
Result: PASS
Wrote JSON-MergePatch-0.01.tar.gz
Upload to CPAN
Release to CPAN ? [y/n]   y
registering upload with PAUSE web server
POSTing upload for /user/home_directory/git/cpan/JSON-MergePatch/.build/ilpDOKuE/JSON-MergePatch-0.01.tar.gz to https://pause.perl.org/pause/authenquery
PAUSE add message sent ok [200]
Name: JSON::MergePatch
Abstract: JSON Merge Patch implementation
Version: 0.01
[JSON-MergePatch] $ git commit -a -m Checking in changes prior to tagging of version 0.01.
Changelog diff is:
diff --git a/Changes b/Changes
index 643c7bc..dae7daa 100644
--- a/Changes
+++ b/Changes
@@ -2,5 +2,7 @@ Revision history for Perl extension JSON-MergePatch

 {{$NEXT}}

+0.01 2015-07-02T18:29:20Z
+
     - original version

[master 3bf0db2] Checking in changes prior to tagging of version 0.01.

 2 files changed, 17 insertions(+), 1 deletion(-)
Pushing to origin
[JSON-MergePatch] $ git push origin master
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 831 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
To git@github.com:sojiro14/JSON-MergePatch.git

   9c8c207..3bf0db2  master -> master

[JSON-MergePatch] $ git tag 0.01
[JSON-MergePatch] $ git push origin tag 0.01
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:sojiro14/JSON-MergePatch.git

 * [new tag]         0.01 -> 0.01

Removing /user/home_directory/git/cpan/JSON-MergePatch/.build/ilpDOKuE

テストが実行された後、CPAN にリリースされました。最後にその時点の tag が切られて完了。

ついに CPAN モジュールをリリースしてしまいました。メンテナンスちゃんとしなくては。

参照

CPAN モジュールのための雛形を作る

いよいよ CPAN モジュールを作ろうと思います。

しかし既存の CPAN モジュールを見てみると本体のプログラムの他に見慣れないファイルがちらほら。。。

正直どんなファイル群で CPAN モジュールを構成すれば良いのか分かっていないわけです。

そんな悩みを解決してくれたのが Minilla モジュールです。

Minilla のインストール

Minilla は CPAN モジュールなので cpanm コマンドでインストールできます。

$ cpanm Minilla
--> Working on Minilla
Fetching http://cpan.metacpan.org/authors/id/T/TO/TOKUHIROM/Minilla-v2.4.1.tar.gz ... OK
Configuring Minilla-v2.4.1 ... OK
...
Building and testing Minilla-v2.4.1 ... OK
Successfully installed Minilla-v2.4.1
11 distributions installed

雛形の作成

Minilla がインストールできたら早速 CPAN モジュールの雛形を作ります。 minil new Your::Module で作成できます。

今回は JSON::MergePatch というモジュールを作ります。

$cd ~/git/cpan
$ minil new JSON::MergePatch
Writing lib/JSON/MergePatch.pm
Writing Changes
Writing t/00_compile.t
Writing .travis.yml
Writing .gitignore
Writing LICENSE
Writing cpanfile
Initializing git JSON::MergePatch
[JSON-MergePatch] $ git init
Initialized empty Git repository in /user/home_directory/git/cpan/JSON-MergePatch/.git/
Retrieving meta data from lib/JSON/MergePatch.pm.
Name: JSON::MergePatch
Abstract: It's new $module
Version: 0.01
fatal: bad default revision 'HEAD'
[JSON-MergePatch] $ git add .
Finished to create JSON::MergePatch

これで雛形ができました。

そしてこれから雛形を編集していくわけですが、自分で編集するのは基本的に以下のファイルのみです。

  • lib/ 配下のプログラム
  • t/ 配下のテストプラグラム
  • cpanfile

以下のファイルはそれぞれ minil hoge コマンド実行時に自動で編集されます。

  • Changes: リリース時に更新される
  • META.json: cpanfile に合わせて更新される
  • README.md: lib/Your/Module.pm の記述から更新される

つづく

次回はいよいよ CPAN へ公開する際の手順を書こうと思います。

参照

Homebrewをupdateしよう

以前の記事で Homebrew を使って Docker のもろもろをインストールしたが、実はそのときインストールされたツールのバージョンが古く、それが原因で作業が少し詰まった。

そんなときは Homebrew の update である。

Homebrew を update する

おもむろに

$ brew update

新しい FORMULA 、更新された FORMULA 、削除された FORMULA の一覧が表示されて Homebrew の update が完了する

古いモジュールの upgrade

Homebrew を update しただけでは、すでにインストールされているモジュールは新しくならない

$ brew upgrade [FORMULA]

で最新バージョンに upgrade する

今後 Homebrew を使うときは参照する FORMULA のバージョンも気にしたい

JSON Schema のバリデーション

JSON Schema を勉強中であります。

その名の通り JSON でリソースそのものやリソースの操作まで表現できる面白いツールだと思います。

しかし、 JSON Schema は往々にして複雑になりがちで、書く量が多くなると typo も増えてきます。

そこで今回は JSON Schema のバリデーションに使えるツールをメモ程度に書いておきます。

validate-schema コマンド

まずは validate-schema コマンドから。簡単なバリデーションをしてくれる。

gem の json_schema パッケージに入っているのでインストール

$ gem install json_schema
Password:
Fetching: json_schema-0.6.0.gem (100%)
Successfully installed json_schema-0.6.0
...
1 gem installed

インストールできたらオプションに -d をつけて実行

これがバリデーションに通った例

$ validate-schema -d json_schema/directory/test.json
json_schema/directory/test.json is valid.

バリデーションに落ちるとこうなる

$ validate-schema -d json_schema/directory/test.json
json_schema/directory/test.json: Invalid JSON. Try to validate using `jsonlint`.

なんと別のツールを使って確かめろということなので、以下につづく。

jsonlint コマンド

さて、 validate-schema に jsonlint を使え、と言われたので早速インストールする

$ npm install jsonlint -g
npm http GET https://registry.npmjs.org/jsonlint
npm http 200 https://registry.npmjs.org/jsonlint
...
/usr/local/bin/jsonlint -> /usr/local/lib/node_modules/jsonlint/lib/cli.js
jsonlint@1.6.2 /usr/local/lib/node_modules/jsonlint
├── nomnom@1.8.1 (underscore@1.6.0, chalk@0.4.0)
└── JSV@4.0.2

インストールが完了したら早速チェック

$ jsonlint json_schema/directory/test.json
[Error: Parse error on line 20:
..."],                }            },   
----------------------^
Expecting 'STRING', got '}']

今度はバリデーションに落ちる理由と場所を示してくれるのですぐに修正できる

だいたいバリデーションに落ちるときは , のつけ過ぎが多い

これらのツールで無駄にハマる時間をなくしたいものです。

validate-schema コマンド(再)

今回は JSON Schema 単体のチェックだったので validate-schema コマンドが使い勝手悪く見えるので補足

もともとは、ある JSON データが JSON Schema に則っているかのバリデーションをするツールである

$ validate-schema json_schema/check.json test.json 
test.json#/emotion: failed schema #/properties/emotion: embarrassment is not a member of ["pleasure", "anger", "sadness", "enjoyment"].

参照

PAUSE ID の取得

いま私は日本の Perl シーンにおける名立たるプログラマの方々の元で仕事させていただくという大変ありがたい立場にいるのですが、常々

** OSS に対する活動が成長の大きな糧になるからチャレンジすべし **

とアドバイスを受けています。

ところが初めてその言葉を受けてから既に1年以上経とうというのに何もしていない。これは本当にいかんと思ってとにかく CAPN に貢献してみようと。

そこで調べてみると PAUSE ID なるものが必要なようなので取得までの過程をここへメモします

PAUSE ID の取得

PAUSE は The Perl Authors Upload Server の略称で、ここから CPAN へのアップなどするよう

ここ から登録を開始する

各項目に入力してアカウント申請を行う

full name の欄はそれっぽい名前じゃないとはじかれるが、後から変えられる

申請を行うと、しばらくしてアカウント発行の通知が登録したメールアドレスに届く

この通知は人によって届くまでの時間にばらつきがあるようだが、今回は申請したその日のうちに来た

通知にはパスワード変更ページへのリンクと暫定のパスワードが記載されているので、登録した ID と暫定パスワードで Basic 認証を突破してパスワードを設定する

アカウントが発行されると Edit Account Info というメニューへアクセスできるようになる

ここに

The email address [id]@cpan.org should be configured to forward mail to ...

という項目があるので、 [id]@cpan.org へのメールを受け取るメールアドレスを設定する

ここで設定しておかないと後々 [id]@cpan.org に対するメールが受け取れず不便を被るので要設定とのこと

Gravatar の設定

Gravatar は Email アカウントにアイコンを紐づけて様々なサービスで使えるようにするサービスで、 GitHub などでも使われている

https://ja.gravatar.com/

Gravatar に PAUSE ID に紐づいたアドレスでアイコンを設定することで CPAN のアカウントへアイコンを設定することができる

[id]@cpan.org  # 設定するメールアドレス

既に Gravatar のアカウントがある場合は「メールアドレスの追加」から上記アドレスを追加すればよい

新たに Gravatar のアカウントを取得する場合は注意が必要なようである。 @cpan.org のメールアドレスが前項の PAUSE ID 取得の際に自分のメールアドレスへ転送されるよう設定してからでないと、メールアドレスの認証が取れず、 Gravatar のアカウント取得に失敗するようだ。

{% img /images/cpan/gravatar.png %}

Gravatar の設定が済むと PAUSE アカウントに設定したアイコンが表示されるようになる

{% img /images/cpan/sojiro.png %}

さて、アカウントは取得した。後はコードを書いて上げるだけ。

やるしかないのです。

参照

Webからデバイスのカメラを起動する

Web からデバイスのカメラを起動してみたいと思いたち、少し調べて見たことのメモ

準備

以前のエントリ Node.jsを使ってWeb Serverを作ってみました で立てたサーバーで実験してみます

ベースとなるコード

このコードに手を入れていきます

```javascript web.js var http = require('http'); var server = http.createServer();

server.on('request', function(request, response) { response.writeHead(200, {'Content-Type': 'text/html'}); response.write('Hello World'); response.end(); }); server.listen(****, 'xxx.xx.x.xxx'); console.log('server listening...');


## コードの全体像

最終的なコードはこちら。かなり手抜きしてます

[こちら](http://python-gazo.blog.jp/html5/javascript/webcamera) を参考にさせていただきました

```javascript web_camera.js
var http = require('http');
var server = http.createServer();
var _html = (function () {/*
<!doctype html>
<html>
<head>
  <title>Web Camera</title>
  <script type="text/javascript">
function capCamera(){
  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia;
    window.URL = window.URL || window.webkitURL;

  var video = document.getElementById("camera");
  var localStream = null;
  navigator.getUserMedia({video: true, audio: false},
  function(stream) {
    console.log(stream);
    video.src = window.URL.createObjectURL(stream);
  },
  function(err) {
    console.log(err);
  }
  );
} 
  </script>
</head>
<body>
   <input type="button"  value="Web Camera" onClick="capCamera()">
   <br>
   <video id="camera" width="640" height="480" autoplay="1" ></video>

</body>
</html>
*/}).toString().replace(/(\n)/g, '').split('*')[1];

server.on('request', function(request, response) {
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write(_html);
    response.end();
});
server.listen(****, 'xxx.xx.x.xxx');
console.log('server listening...');

HTML 部分

HTML の部分をみてみます

<body>
   <input type="button"  value="Web Camera" onClick="capCamera()">
   <br>
   <video id="camera" width="640" height="480" autoplay="1" ></video>
</body>

構成はボタンと、カメラからの映像をキャプチャする範囲の2つだけ

ボタンには capCamera() という関数が紐づけられています

JavaScript 部分

次に JavaScript の部分をみてみます

function capCamera(){
  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || window.navigator.mozGetUserMedia;
    window.URL = window.URL || window.webkitURL;

  var video = document.getElementById("camera");
  var localStream = null;
  navigator.getUserMedia({video: true, audio: false},
  function(stream) {
    console.log(stream);
    video.src = window.URL.createObjectURL(stream);
  },
  function(err) {
    console.log(err);
  }
  );
} 

ここで navigator インターフェースの getUserMedia() メソッドを使用しているのがわかります

getUserMedia の構文

navigator.getUserMedia ( constraints, successCallback, errorCallback );
引数 必須 / オプショナル 説明
constraints 必須 successCallback に渡されるLocalMediaStream オブジェクトがサポートするメディアタイプ。
successCallback 必須 LocalMediaStream オブジェクトが取得できた場合、呼び出されるコールバック関数。
errorCallback オプショナル (Firefox では必須) 呼び出しが失敗した際に実行されるコールバック関数。最近の Firefox では必須となっています。省略された場合、 NS_ERROR_XPC_NOT_ENOUGH_ARGS error がスローされます。

constraints

video, audio の二つの属性に対して真偽値を指定する

successcallback

LocalMediaStream が引数として渡されるので window.URL.createObjectURL() メソッドにそのまま渡してオブジェクトの URL を取得する

このように取得したビデオストリームの URL を video の DOM に渡すことで video 領域にビデオを表示します

JavaScript 内のヒアドキュメント

今回は横着して web_camera.js の中に HTML をすべてヒアドキュメントで記述しました JavaScript 内のヒアドキュメントに関してはちょっとしたテクニックがあるようなのでそれはまた次の機会に書こうと思います。

Web からデバイスのカメラを操作できるというのはとても面白いのですが、今回扱ったメソッドはまだまだ一部のブラウザでしかサポートされていないので、特にモバイルで使えるようになったらもっと面白くなるのに、という感想をもってこのエントリを終わります。

参照

xdg-open コマンドとは

以前 初めてのYeoman (Grunt/Bowerを使ってみる) というエントリで Grunt を実行したときに

Warning: Command failed: /home/sojiro/yeoman/angular_fullstack/node_modules/open/vendor/xdg-open: line 584: xdg-mime: コマンドが見つかりません

と怒られたことがあったので xdg-open コマンドについて少し調べてみます

xdg-open コマンドのインストール

xdg-open の実体はシェルスクリプトである

すんなりインストールできるかと思いきや普段の CentOS に入れるのに手こずってしまった

どうやら Ubuntu との相性が良いようなので Vagrant で Ubuntu を立ち上げてそこでインストールしてみる

Ubuntu のセットアップ

Vagrant で Ubuntu 環境をセットアップする

まずは box のインストールから

$ vagrant box add ubuntu http://goo.gl/8kWkm
==> box: Adding box 'ubuntu' (v0) for provider: 
   box: Downloading: http://goo.gl/8kWkm
==> box: Successfully added box 'ubuntu' (v0) for 'virtualbox'!
$ vagrant box list
centos64 (virtualbox, 0)
ubuntu   (virtualbox, 0)

box がセットアップできたら立ち上げまで行ってしまう

$ mkdir ubuntu
$ cd ubuntu/
$ vagrant init ubuntu
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
$ ls
Vagrantfile
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: ubuntu_default_1432117537476_54763
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
   default: Adapter 1: nat
==> default: Forwarding ports...
   default: 22 => 2200 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...

立ち上がったら以下のコマンドで Ubuntu 環境に入り、インストールの準備が完了する

$ vagrant ssh
Welcome to Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-32-generic x86_64)

* Documentation:  https://help.ubuntu.com/

 System information as of Wed May 20 07:30:10 BRT 2015

 System load:  0.0               Processes:           73
 Usage of /:   11.7% of 7.87GB   Users logged in:     0
 Memory usage: 1%                IP address for eth0: 10.0.2.15
 Swap usage:   0%

 Graph this data and manage this system at https://landscape.canonical.com/

New release '14.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

インストール

ここからいよいよ Ubuntu に xdg-open をインストールしていく

最初から入ってたらラッキーだなーと思いつつ打ってみる

$ xdg-open
The program 'xdg-open' is currently not installed.  You can install it by typing:
sudo apt-get install xdg-utils

思いがけず大ヒントが返ってきたので従う

xdg-utils は xdg-open を内包するパッケージである

$ sudo apt-get install xdg-utils
Reading package lists... Done
Building dependency tree
...
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

エラーになってしまった

しかしまたヒントがあるので従う

$ sudo apt-get install xdg-utils --fix-missing
Reading package lists... Done
Building dependency tree
...
Extracting templates from packages: 100%
Preconfiguring packages ...
Selecting previously unselected package ttf-dejavu-core.

晴れてインストール完了

使ってみる

  • テキストファイル: 普通に開ける
  • 画像ファイル: 開けるメソッドがなくエラー(環境立ち上げたばかりなので)

ディレクトリを指定

$ mkdir test
$ touch test/file
$ xdg-open test/

{% img /images/xdg_open/directory.png %}

URL を指定してみる

$ xdg-open http://blog.sojiro.me

{% img /images/xdg_open/blog.png %}

$ xdg-open http://google.com

{% img /images/xdg_open/google.png %}

ブラウザはないが URL を指定すると CUI 上で Web ページが開ける

参照