2015年12月6日日曜日

CentOS7のChromeでWebページが開けないトラブル

CentOS7でChromeを使用していたらある日突然Webページが開けないケースが発生しました。 エラー内容

ERROR:child_process_launcher.cc(445)] Failed to launch child process ERROR:zygote_host_impl_linux.cc(374)] Did not receive ping from zygote child ERROR:zygote_linux.cc(573)] Zygote could not fork: process_type renderer numfds 5 child_pid -1 

どうやらSELinuxポリシーの変更によるものの様です。 SELinuxポリシーが更新されていなかったら更新することで治ります。

$ sudo yum update selinux-policy selinux-policy-devel selinux-policy-sandbox

2015年12月4日金曜日

learnyounodeを解いてみる(8問目)

learnyounode [ HTTP COLLECT]


1つ目のコマンドライン引数は URL 文字列です。 そのURL文字列を使ってHTTP のデーターをロード (※)するアプリを書いてください。 サーバから全て(最初のイベントだけではなく)のデータを集め、次の2行をコンソールに出力して下さい。 1行目は文字数です。2行目はサーバから受け取った全てのデータを文字列で出力してください。



こちらも出題内容が解りづらいかもしれませんが、バッファから得られるデータを纏めて文字数とその文字列を出力するだけです。 先回のものを少し変えるだけで出来そうですね。
response.on("data")で得られるデータはバッファなのでそれを繋ぎます。
あとはresponse.on("end")でlengthを使い文字数を出力し、文字列そのものを出力してやればいいだけです。

httpcollect.js
var http = require('http');

var url = process.argv[2];

http.get(url, function(res) {
    var out = "";
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
    out += chunk;
    });
    res.on('end', function() {
    console.log(out.length);
    console.log(out);
    });
    res.on('error', function(err) {
     console.error("Error: " + err.message);
    });
});



さて、正解はこれでいいのですが、問題のヒントにblかconcat-streamパッケージを使ってくださいとあります。これら外部パッケージを使うこともNodeの魅力です。これを使って解いてみましょう。

これらはサードパーティ製なので使用するにはnpmでインストールする必要があります。

 $ npm install bl

blパッケージはBufferListの略でバッファをリストで加工できる様にしたパッケージでバッファを利用しやすくしています。
主な使い方は以下で説明されてます。
bl

特に利便性が高いのはコールバックを引数に持つのでpipeで繋げられることです。
ヒントにもあるのでその使用法で書きましょう。

response.pipe(bl(function(err, data) { }));
blのサイトには
// `data` is a complete Buffer object containing the full data と書いてあります。
つまりデータにはすべてのバッファを含めた状態で渡されるとあるので上と同じ処理をして完成です。気をつけることはbufferはバイナリのままなのでtoString()で文字列に変更することでしょうか?

blcollect.js
var http = require('http');
var bl = require('bl');

var url = process.argv[2];

http.get(url, function(res) {
    res.pipe(bl(function(err, data) {
 if(err) return console.error(err);
   console.log(data.length);
   console.log(data.toString());
    }));
});



# おめでとう!

「HTTP 集める」に対するあなたの回答は合格です!

これが正式な回答です(もしあなたの回答と比較してみたいならどうぞ):

───────────────────────────────────────────
    var http = require('http')
    var bl = require('bl')
    
    http.get(process.argv[2], function (response) {
      response.pipe(bl(function (err, data) {
        if (err)
          return console.error(err)
        data = data.toString()
        console.log(data.length)
        console.log(data)
      }))  
    })

以上です。

2015年11月24日火曜日

learnyounodeを解いてみる(7問目)

learnyounode [ HTTP CLIENT]


1つ目の引数として指定された URL に、 HTTP で GET を送信する (※)アプリを書いてください。 そのリクエストに対するレスポンスを"data"イベントで受け取り、受け取った全ての文字列を1つずつ改行で区切ってコンソールに書き出してください。


問題は少し説明が分かりにくいですが、ヒントを読むとhttpモジュールのgetを使ってurlから内容をそのまま読めば良いようです。ほぼヒントに書かれている通り書けば良いので問題はないでしょう。

http.get(options, [callback])

httpモジュールはNode入門書では大抵出てくるので何をしているかは理解できるでしょう。

使い方は http.get(url, callback) でいつもの通りコールバックを使用しますが、そのコールバック関数は function callback (response) { /* ... */ } と第一引数がエラーではありません。
response.on()で得られたデータを'data' でエラーを 'error' を取得します。

気をつけるのは得られたデータにresponse.setEncoding()でエンコーディングを適用することです。
まとめると以下のようになります。

get.js

var http = require('http');

var url = process.argv[2];

http.get(url, function(res) {
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      console.log(chunk);
    }).on('error', function(err) {
      console.error("Error: " + err.message);
    });
});


# おめでとう!

「HTTP クライアント」に対するあなたの回答は合格です!

これが正式な回答です(もしあなたの回答と比較してみたいならどうぞ):

──────────────────────────────────
    var http = require('http')
    
    http.get(process.argv[2], function (response) {
      response.setEncoding('utf8')
      response.on('data', console.log)
      response.on('error', console.error)
    })




2015年11月21日土曜日

learnyounodeを解いてみる(6問目)

learnyounode [MAKE IT MODULAR]


指定したディレクトリから、拡張子でフィルタしたファイルのリストを出力するプログラムを書いてください。 コマンドライン引数の1つ目はディレクトリ名、2つ目は拡張子です。 フィルタリングしたファイル名を1行ずつコンソールに出力してください。非同期 I/O を使ってください。 

module ファイルに処理の大部分を書いてください。module には、3つの引数を取る関数を一つだけ定義してください。 その関数の引数は ディレクトリ名・ファイル拡張子・コールバック関数、という順序です。


次は意外に難問です。learnyounode一の難問と言っていいかもしれません。
問題としては先回のものをそのままモジュールにするだけですが、モジュールにするにはNodeのモジュール化とコールバック関数の使い方にある程度慣れなければなりません。
今までrequire関数で呼び出しのみ使っていたモジュールを自作するのです。

モジュール化自体はいたって簡単です。
exportsにプロパティやメソッドを代入すればいいだけです。

calc.js

exports.add = function(n1, n2) {
    return n1 + n2;
};

そして使用する側はファイル名を指定して呼び出します。

main.js

var calc = require('./calc');

console.log(calc.add(1, 2));

$ node main.js
3


簡単です。ファイル名は拡張子あり'./calc.js'でも無し'./calc'でも行けますがローカルモジュールの場合は先頭にパス'./'が必要です。

ただし、上の書き方だとオブジェクトを代入するとエラーが出ます。Nodeでオブジェクトを代入するにはmodule.exportsを使います。module.exportsは上位互換だと思ってください。なのでNodeでモジュール化するならmodule.exportsを使っておけばいいです。

Modules

先ほどのモジュールをオブジェクトで代入するとこうなります。

calc.js

module.exports = {
    add: function(n1, n2) {
      return n1 + n2;
    }
};


こちらを使っても同じ結果になるはずです。JavaScriptのオブジェクトを知っていればそれほど問題ないでしょう。
以下のようにすればメソッドをどんどん追加できます。

calc.js

module.exports = {
    add: function(n1, n2) {
      return n1 + n2;
    },
    sub: function(n1, n2) {
      return n1 - n2;
    },
    mul: function(n1, n2) {
      return n1 * n2;
    },
    div: function(n1, n2) {
      return n1 / n2;
    }
};


main.js

var calc = require('./calc');

console.log(calc.add(5, 3));
console.log(calc.sub(5, 3));
console.log(calc.mul(5, 3));
console.log(calc.div(5, 3));


$ node main.js
8
2
15
1.6666666666666667


今回の問題にはいろいろ制約があります。

作成する module には、以下の4つの制約があります。
  • 正しい引数を取る関数を定義してください。
  • エラー、もしくはデータを引数に取るコールバック関数を一度だけ呼び出してください。 
  • 2つ目の制約以外には何も変えないでください(グローバル変数や標準出力など)。
  • 発生する可能性のあるエラーは全てコールバック関数に渡してください。 

関数の引数がディレクトリ名・ファイル拡張子・コールバック関数という指定なので先回作ったものをそのまま引数3つの関数でラップしてみます。

findfile.js


var fs = require('fs');
var path = require('path');

var dir = process.argv[2];
var ext = process.argv[3];

/*
  ディレクトリ名・ファイル拡張子・コールバック関数の3つの引数を定義する。
  とりあえずコールバックは定義のみ
 */
var find = function(dir, ext, callback) {   
  //先回作った部分
    fs.readdir(dir, function(err, list) {
     if(err) throw err;
     for(var i in list) {
       if(path.extname(list[i]) == '.' + ext) {
         console.log(list[i]);
       }
     }
   });
}

//作った関数の実行
find(dir, ext, function() {});


$ node findfile.js . txt
test.txt
words.txt


ちゃんと動作しますね。これを出力でなくリストの返り値として変更してみます。問題は得られたリストをどうやって返すかですがここでコールバック関数を使用します。与えられたコールバック関数の引数に渡せば呼び出し先で結果が得られます。

findfile.js

var fs = require('fs');
var path = require('path');

var dir = process.argv[2];
var ext = process.argv[3];

/*
  ディレクトリ名・ファイル拡張子・コールバック関数の3つの引数を定義する。
 */
var find = function(dir, ext, callback) {
    fs.readdir(dir, function(err, list) {
      var files = [];
      if(err) throw err;
      for(var i in list) {
       if(path.extname(list[i]) == '.' + ext) {
         files.push(list[i]);
       }
      }
      //ここで得られた結果を引数として渡す。
      callback(null, files);
  });
}

//コールバック関数から取り出します。
find(dir, ext, function(err, list) {
    console.log(list);
});

これを実行すれば配列ですが先ほどと同じ結果が得られるはずです。
ここまで来れば簡単ですね。あとはエラー内容を指定どおりに処理して、モジュール化し使う側で得られた結果をイテレートするだけです。

findfile.js

var fs = require('fs');
var path = require('path');

module.exports = function(dir, ext, callback) {
    fs.readdir(dir, function(err, list) {
      var files = [];
      if(err) return callback(err);
      for(var i in list) {
        if(path.extname(list[i]) == '.' + ext) {
          files.push(list[i]);
        }
      }
      callback(null, files);
    });
}


usefindfile.js

var findfile = require('./findfile');
var dir = process.argv[2];
var ext = process.argv[3];

findfile(dir, ext, function(err, list) {
    if(err) throw err;
    list.forEach(function(file) {
      console.log(file);
    });
});




$ learnyounode verify usefindfile.js 

・・・・

# おめでとう!

「モジュラーにしましょう」に対するあなたの回答は合格です!

これが正式な回答です(もしあなたの回答と比較してみたいならどうぞ):

───────────────────────────────────────────
solution.js:

    var filterFn = require('./solution_filter.js')
    var dir = process.argv[2]
    var filterStr = process.argv[3]
    
    filterFn(dir, filterStr, function (err, list) {
      if (err)
        return console.error('There was an error:', err)
    
      list.forEach(function (file) {
        console.log(file)
      })
    })

───────────────────────────────────────────
solution_filter.js

    var fs = require('fs')
    var path = require('path')
    
    module.exports = function (dir, filterStr, callback) {
    
      fs.readdir(dir, function (err, list) {
        if (err)
          return callback(err)
    
        list = list.filter(function (file) {
          return path.extname(file) === '.' + filterStr
        })
    
        callback(null, list)
      })
    }

2015年11月20日金曜日

learnyounodeを解いてみる(5問目)

learnyounode [ FILTERED LS]

拡張子によってフィルタしたファイルリストをコンソールに出力するアプリを書いてください。


5問目は、指定した拡張子のファイルを列挙するアプリです。シェルコマンドで言えば「find -name ".拡張子"」の様な結果になるということですね。
 1つめの引数にフォルダのパスを入れ、2つめの引数に拡張子を指定します。2つめの拡張子は拡張子名のみ、("."抜き)で指定とあります。

とりあえず、ファイルの列挙から始めましょう。
非同期でとありますので、ファイル列挙は fs.readdir を使用します。第一引数にパス、第二引数にはコールバック関数です。 Nodeのコールバック関数はcalback(err, list)のパターンが定番なので覚えておきましょう。listは得られたファイルの配列です。

fs.readdir


readdir.js
var fs = require("fs");
var dir = ".";

fs.readdir(dir, function(err, list) {
    if(err) throw err;
    for(var i in list) {
 console.log(list[i]);
    }
});

上の例ではパスがカレントディレクトリで固定されているので引数を指定せず、そのままカレントディレクトリ内のファイルが列挙されるはずです。
if (err) throw err; もエラーをthrowさせるNodeのイディオムなので無くても正常であれば動作します。
forは得られた配列を展開しているだけなので、イテレータ「files.forEach(function (file) { }」でもいけます。

得られたファイルリストから拡張子を抜き出すには、文字列操作を使っても構いませんがヒントに拡張子を抜き出すNodeのpathモジュールを使うと役に立つと書いてあるのでpathモジュールのextname関数を使用します。extname関数は引数にファイルを入れると拡張子だけ抜き出してくれます。それを判定に使えばいけますね。

path.extname


気をつけることは引数には拡張子名だけ指定してextnameで抜き出せる拡張子が"."付きだということです。なので"."を足してから比較します。
あとは引数と得るのは先回使ったprocess.argv[N]なので組み合わせて完了です。

extname.js
var fs = require("fs");
var path = require("path");

var dir = process.argv[2];
var ext = process.argv[3];

fs.readdir(dir, function(err, list) {
    if(err) throw err;
    for(var i in list) {
   if(path.extname(list[i]) == '.' + ext) {
      console.log(list[i]);
   }
    }
});

$ learnyounode verify extname.js 

...................

# おめでとう!

「LSのフィルター」に対するあなたの回答は合格です!

これが正式な回答です(もしあなたの回答と比較してみたいならどうぞ):

─────────────────────────────────────────
    var fs = require('fs')
    var path = require('path')
    
    fs.readdir(process.argv[2], function (err, list) {
      list.forEach(function (file) {
        if (path.extname(file) === '.' + process.argv[3])
          console.log(file)
      })
    })

2015年11月9日月曜日

learnyounodeを解いてみる(4問目)

learnyounode [MY FIRST ASYNC I/O! ]

非同期処理 をするファイルシステムのメソッドを使ってファイルの改行数を出力するアプリを書いてください。 cat file | wc -l と同じようなアプリです。 アプリの1つ目のコマンドライン引数は、そのファイルへのパスです。


4問目は3問目をただ非同期にしただけです。ヒントにある様にNodoでは非同期の文化が前提です。
なぜならNode.jsノンブロッキングなI/Oを実装することで様々な優位性を引き出しているからです。Node自体の解説は置いておくとしてNodeでノンブロッキングな書き方を実装するにはコールバック関数によって行われます。JavaScriptをある程度書いたことのある人ならご存知でしょう。

同期型のコード
var data = $.post(fname);
//上の処理が終わるまで実行されない
console.log(data)


非同期型のコード
$.post(fname, function(data) {
  console.log(data)
});
//上の処理が終わらなくても実行される
console.log("OK")

つまり、3問目の処理をコールバック関数に納めれば良いだけです。


filelinesAsync.js
var fs = require('fs');
var filename = process.argv[2];

fs.readFile(filename, function(err, data) {
    var lines = data.toString().split('\n').length - 1;
    console.log(lines);
});


$ learnyounode verify filelinesAsync.js 

# おめでとう!

「初めての非同期I/O!」に対するあなたの回答は合格です!



2015年11月8日日曜日

PythonでCGIスクリプトページが表示されない時

CGIスクリプトでスクリプトが実行されない時


PythonスクリプトでCGIスクリプトをサーバーから実行させようと思ってWebページを開こうと思っても表示されない時があります。
様々なケースが考えられますが、単純なミスの場合もあります。

サーバーを起動させているシェルのエラーを見ながら何がいけないのか疑ってみましょう。


表示されない場合(エラーに何も出ないケース)


パスは合っているのにWebページに何も表示されない場合。シェルにも異常が出てない場合はContent-Typeに全角文字が混ざっていたりスペル違いがあったりそのあたりを疑ってみましょう。

表示されない場合(エラーに「FileNotFoundError: [Errno 2] No such file or directory: 」が出るケース)


同じくWebページが表示されずシェルに「FileNotFoundError: [Errno 2] No such file or directory: 」のエラーが出る場合。スクリプトの先頭行シェバング行のパスが合っていない可能性が高いです。
通常のスクリプトは実行出来てもCGIサーバ-から実行する場合、相対パスからだと辿れないためそのエラーが発生します。絶対パスに書き換えてみてください。
現在のPythonのパスは「$ which python」で現在のPythonの実行パスを表示させ。出てきたパスをコピーして「ls -la 」で表示させるとリンクされている絶対パスを取り出せるのでそれをコピーしてシェバング行を書き換えてから実行してみてください。ただしローカル環境の絶対パスそのままだと移植性に乏しいので #!/usr/bin/env python3 を使用するかリンクを貼っておいた方が後々楽でしょう。

その他のエラー


スクリプト自体のパスが違っていたり、スペルミスでスクリプトファイルが存在してなかった場合にはシェルに「code 404, message No such CGI script」エラーが出てWebページに「Error response Error code: 404」が表示されます。

後は、スクリプトのパーミッションが(755)などに許可されていなかったり他から移動させたファイルなどやSELinuxのコンテキストが違っていたりしていたりする(code 403, message CGI script is not executable )のでそのあたりを疑ってみましょう。

2015年11月5日木曜日

learnyounodeを解いてみる(3問目)

learnyounode [MY FIRST I/O!]

同期処理 をするファイルシステムの関数を使ってファイルの改行文字(\n)の数を出力するアプリを書いてください。 cat file | wc -l と同じようなアプリです。 アプリの1つ目のコマンドライン引数は、そのファイルへのパスです。テスト用のファイルを作る必要はありません。


3問目はファイルを読み込んでそのファイル内に書かれている文字列の行を表示するというアプリです。ファイル読み込みは各プログラミング言語でも必須の機能なのですが、Nodeの親と言えるJavaScriptにはその特殊な立場やセキュリティの問題からファイルを扱う機能がありませんでした。
ですからビルトインオブジェクトにもFileオブジェクトはありません。
ただしAjaxなどでサーバからファイルを取得する限定的な扱いは存在しましたし、HTML5から制限のある中でローカルファイルを扱えるFileクラスも定義されました。
JavaScriptがそのようなことなのでNodeでどうファイルを扱うか困ってしまいそうですが、幸いNodeでファイルを読み込むにはfsというモジュールを使用することで扱えます。fsはFile Systemの略だそうです。

File System

問題で気をつけることは同期処理が指定されていることです。Nodeでは非同期が売りなので同期処理の方が使用頻度は少ないでしょうが、振る舞いとしては同期処理のほうが簡単なので問題として出されたのでしょう。
ファイルを同期処理で読み込むにはreadFileSyncプロパティを使用します。

fs.readFileSync

それを踏まえてファイルを読み込んで見ましょう。

readFile.js

var fs = require('fs');

var filename = "読み込むファイル"
var data = fs.readFileSync(filename, 'utf8');
console.log(data);


これでファイルの内容が読み込めました。
後は改行('\n')を数えるだけです。ヒントには得られたバッファを文字列に変えてから改行文字をsplitメソッドで区切れば改行ごとに分割された文の配列になるのでその要素数を数えれば改行を数えたことと同じになると解説してくれています。ただし最期の改行で句切られた空要素も入るのでそれは-1することに注意します。

コマンドライン引数からファイルを読み込んでと書いてあるので前回のprocess.argv[2]でファイル名を引き取るようにします。

以上を合わせて

filelines.js

var fs = require('fs');
var filename = process.argv[2];

var data = fs.readFileSync(filename, 'utf8');
var lines = data.toString().split('\n').length - 1;
console.log(lines);


$ learnyounode verify filelines.js 

以上で合格です。

2015年11月4日水曜日

learnyounodeを解いてみる(2問目)

learnyounode [BABY STEP]

問題: 以上の整数をコマンドライン引数として受け取り、それらを足し合わせた値をコンソール(stdout)に出力するコマンドラインアプリを書いてください。


さて、この問題にはコマンドライン引数が必要ということなので、まずはNodeでコマンドライン引数を取る方法を調べます。 ヒントにはNodeでコマンドライン引数を取るにはprocessオブジェクトのargvプロパティを使用すると書いてあります。
  process.argv

processはグローバルオブジェクトなのでモジュールを呼ぶことなしに使えます。

process.argvから取れる引数は配列であり1つ目の引数は"node"で、2つ目の引数は"実行ファイルのパス"で3つ目から入力した引数となっています。

まずこのコードでどのように引数が取れるか試してみましょう。

argv.js

console.log(process.argv)

$ node argv.js 1 2 3
[ 'node',
  '.../node/test/argv.js',
  '1',
  '2',
  '3' ]



コマンドライン引数はスペースごとに一つの要素としてすべて文字列の配列で取られていることが分かります。
従って第三引数から取って、数値に変換することが理解できれば簡単です。

sum.js

var len = process.argv.length;
var sum = 0;
for(var i = 2; i < len; i++) {
    sum += Number(process.argv[i]);
}
console.log(sum);

$ learnyounode verify sum.js


✓ 回答内容は想定回答とマッチしました

# おめでとう!

「ベイビーステップ」に対するあなたの回答は合格です!

正式な回答が出てきますがヒント通りに書いたのでほぼ同じでしたね。

2015年11月3日火曜日

learnyounodeでNode.jsを段階的に学ぶ

learnyounodeとは?

learnyounodeとは、NodeSchoolが提供するnodeモジュールのworkshoperによって作られる対話形式のチュートリアルです。
コンソールさえあれば簡単に学ぶことが出来るのでお手軽です。

元は英語ですが有志たちにより多言語化されており日本語にも対応しているので言語選択により日本語で学ぶことが出来ます。

learnyounodeの難易度としては、JavaScriptの基本はおさえており、Node.jsも入門から基本操作や幾つかのモジュールを触ったことがあれば解けるのではないでしょうか?
問題はNodeの基本といえる機能を一通り出してくれるので全問解ければNodeの概要は理解できたと言えるかもしれません。Nodeの理解や力試しにはもってこいです。

インストール

$ npm install -g learnyounode




言語選択がない場合はlearnyounode-jpをインストールしてください。

$ npm install -g learnyounode-jp

インストールできたらlearnyounodeコマンドで起ち上げます。

$ learnyounode

そこで言語選択をするか -l ja オプション追加で日本語に変換できます。
問題が出されたらその条件のアプリを作成し verify コマンドで正解かどうか検証します。



$ learnyounode verify [作成したファイル]

で正解すると[完了済み]が付きます。

他にもチュートリアルが幾つか用意されています。

NodeSchool



learnyounodeを解いてみる(2問目)
learnyounodeを解いてみる(3問目)
learnyounodeを解いてみる(4問目)
learnyounodeを解いてみる(5問目)
learnyounodeを解いてみる(6問目)
learnyounodeを解いてみる(7問目)
learnyounodeを解いてみる(8問目)

2015年10月5日月曜日

STLのcountを使う(C++)

STLのcount

STLのalgorithmライブラリに含まれるcountはIteratableなオブジェクトに現れる要素の個数を数えるだけのアルゴリズムです。

定義は
template <class InputIterator, class T>
  typename iterator_traits<InputIterator>::difference_type
    count (InputIterator first, InputIterator last, const T& val)
{
  typename iterator_traits<InputIterator>::difference_type ret = 0;
  while (first!=last) {
    if (*first == val) ++ret;
    ++first;
  }
  return ret;
}
となっています。 簡単なアルゴリズムですが要素を数える必要がある場合は使っても良いかもしれません。

使用例:
#include <iostream>
#include <ctime>
#include <vector>
#include <algorithm>

using namespace std;
/* rand() による乱数をカウントする */
void randomTest(const size_t size, const size_t max) {

  vector<int> vec;
  srand((unsigned int)time(NULL));

  for(int i = 0; i < size; i++) {
    vec.push_back(rand() % max);
  }

  for(int i = 0; i < max; i++) {
    const int cnt = count(vec.begin(), vec.end(), i);
    cout << i << "は" << cnt << "個あります" << endl;
  }

}

int main() {

  size_t size = 10000;
  size_t max = 10;

  randomTest(size, max);

  return 0;
}

結果:

0は1021個あります
1は979個あります
2は1016個あります
3は974個あります
4は1013個あります
5は965個あります
6は1025個あります
7は1005個あります
8は1004個あります
9は998個あります

2015年9月26日土曜日

文字列から改行文字を消す(C言語)

文字列の改行を消す

Cで入力文字列を扱っているとfgetsなど改行まで入り込む場合があります。それを消すための簡単なコード。

例:
#include <stdio .h>
#include <string .h>

#define LEN 32

/* 最期に入る改行を取り除く関数 */
void lntrim(char *str) {
  char *p;
  p = strchr(str, '\n');
  if(p != NULL) {
    *p = '\0';
  }
}


int main() {

  char str[LEN];

  puts("[trim]");

  printf("Please input string > ");
  fgets(str, sizeof(str), stdin);

/* trim 前*/
  printf("[%s]\n", str);

  lntrim(str);
/* trim 後 */
  printf("[%s]\n", str);

  return 0;

}
文字列からstrchr関数で文字のある場所を探しだし改行('\n')を('\0')終端に変えています。

strchr関数を使わない場合はループでマッチさせて同じように書き換えます。


/* strchr を使わない改行削除 */
void lntrim(char *str) {
  int i = 0;
  while(1) {
    if(str[i] == '\n') {
      str[i] = '\0';
      break;
    }
    i++;
  }
}


2015年9月12日土曜日

Sassのエラー

SassのError: Inconsistent indentation:


Sassコマンドでcss変換をかけたら「Error: Inconsistent indentation: 1 tab was used for indentation, but the rest of the document was indented using 4 spaces.」というエラーが出ました。一見、タブ関連の間違いかと思いますが、拡張子の間違いでした。Scss形式で書いた場合の拡張子は.scssです。

style.css → style.scss

こういう細かい間違いは気をつけなくてはならないですね。





2015年8月17日月曜日

JavaScriptの配列


JavaScriptの配列

JavaScriptにも他のプログラミング言語の同様に配列を装備しています。 ただし、JavaScriptの配列はCやJavaの様に最初に長さや型が決定される配列では無く、その柔軟さはむしろリストに近いでしょう
実態は配列Objectであり、pushやイテレーターなど様々なプロパティや機能が用意されています。

配列の宣言

JavaScriptの配列の宣言方法は主に2つあります。 配列リテラルを使う方法と、Arrayコンストラクタで生成する方法です。 以下はどちらも同じ配列になります。
//配列リテラル記法
var nums = [10, 20, 30];
document.writeln(nums); //10,20,30

//Arrayコンストラクタ
var nums = new Array(10, 20, 30);
document.writeln(nums); //10,20,30
配列コンストラクタで生成する方法は引数が一つだと、配列の長さになり複数の配列だと配列要素そのものになります。
// 10,20,30の3つの要素を持つ配列
var nums = new Array(10, 20, 30);
document.writeln(nums); //10,20,30

// 10つの空要素を持つ配列
var nums = new Array(10);
document.writeln(nums); // ,,,,,,,,,
この様にArrayコンストラクタは引数が一つか複数かによって生成される配列が変わり紛らわしいので通常は配列リテラルが使われます。 Arrayコンストラクタが有効な場面は配列の長さを先に決めることが出来る点です。
//要素は決定していなが100の長さの配列を確保しています。
var nums = new Array(100);
長さは自然数でなければならないので以下はErrorです
var nums = new Array(0.1); //少数を使用しているSyntexError
var nums = new Array(-1); //マイナスの整数SyntexError
宣言時に変数側にブラケットを書くことは出来ません。このあたりはCなどと違います。
// 10の要素を確保しようとするがSyntaxError
var arr[10] = new Array();
また、いきなりブラケット演算子を使用して配列にすることもできません。 配列変数は最初に配列であると宣言しなければいきなり要素にアクセスできません。
var nums[4] = 5; //SyntaxError いきなり要素に代入している

var nums = []; //まず宣言
var nums[4] = 5; // 前に配列宣言されていれば何番目に入れようとも可能

配列の要素

JavaScriptの配列は柔軟なので、要素数や型を気にせず入れることが出来ます。
var arr = [10, "str", true, function(arg) {}, null, undefined, {}];
console.log(arr); //[10, "str", true, function, null, undefined, Object]
ただし、何も考えずに入れても扱いにくいだけですので、通常はJSONの様に決まったフォーマットなどで有効な使い方でしょう。

配列要素のアクセス

配列要素へのアクセスには、ブラケット演算子[]の0から数えた要素の番号を添え字として指定します。 これはCやJavaなど他の言語と変わりないので特に違和感ないでしょう。
var nums = [10, 20, 30];
document.writeln(nums[1]); // 20が表示される
また配列にはlengthという特殊なプロパティがセットされ全体の長さを取得できます。 これも他の言語と同じような仕組みなので違和感無く使えるでしょう。それによりfor文で全要素にアクセスできます。
var nums = [10, 20, 30];

document.writeln("length = " + nums.length); 
for(var i = 0; i < nums.length; i++) {
    document.writeln(nums[i]);
}
結果:
length = 3
10
20
30

配列とオブジェクト

JavaScriptの配列の実態はArrayオブジェクトです。ですからオブジェクトとしてプロパティを持ちメソッドを使用できます。
var arr = ["one", "two", "three"];

document.writeln(arr.toString()); //文字列として表示
document.writeln(arr); //内部でtoStringメソッドが呼び出される
document.writeln("length = " + arr.length); //lengthプロパティで個数を出力
document.writeln(typeof arr);
結果:
one,two,three
one,two,three
length = 3
object

配列を出力させると自動的にtoStringメソッドが使用され、文字列として表示されます。 typeofでタイプを調べるとobjectが表示されるように実態はオブジェクトです。
lengthプロパティは特殊なプロパティで配列の個数を出力し配列の要素を追加すれば自動的に増えます。
arr.push("four"); //pushプロパティによる追加
document.writeln(arr);
document.writeln("length = " + arr.length);

arr[4] = "five";
document.writeln(arr);
document.writeln("length = " + arr.length);
結果:
one,two,three,four
length = 4
one,two,three,four,five
length = 5

以上は直感的にも理解できるでしょう。 では飛び値の要素を追加したりlength値自体に代入するとどうなるでしょうか?
arr[9] = "ten";
document.writeln(arr);
document.writeln("length = " + arr.length);
document.writeln(arr[5]);

arr.length = 3;
document.writeln(arr);
document.writeln("length = " + arr.length);
結果:
one,two,three,four,five,,,,,ten
length = 10
undefined
one,two,three
length = 3

このように飛び値までの要素はundefinedで埋められ配列の長さは与えられた数まで伸びます。 そしてlength自体に代入するとその長さまでの配列になります。lengthプロパティは単に配列と紐付けられた変数に過ぎないということが分かります。

2015年8月7日金曜日

コマンドプロンプトからC/C++の64ビット用実行ファイルを作る

WindowsのC/C++開発環境

普段Linuxで開発を行なっている方も場合よってはWindowsでC/C++を試す機会があるかもしれません。
そんな中、Visual Studioの様なIDEを一々起ち上げるのは面倒です。Visual Studioにはclコマンドがありちょこっと試したい場合などに重宝します。

clコマンドはデフォルトでは32bitなので64bitで起ち上げてみます。

環境:
OS: Windows8.1(64bit)
IDE: Visual Studio Community 2015

まずVisual Studioはインストールしておいてください。
Visual Studio Communityはフルで24GBくらいあり個人が使うには恐ろしいほど膨大です。

clコマンド使用するには通常「開発者用コマンドプロンプト」というのをクリックします。
このショートカットはWindows8環境で以下の場所にあります。

C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2015\Visual Studio Tools\開発者コマンド プロンプト for VS2015

普通に起ち上げると32bit環境で"C:\VBインストール先\Microsoft Visual Studio 14.0\"が作業フォルダになります。
これを64bit環境でコンパイルしたい場合は、ここに書いてあるとおりvcvarsall.batにamd64という引数をつけて起動させます。

方法: 64 ビットの Visual C++ ツールセットをコマンド ラインから有効にする
https://msdn.microsoft.com/ja-jp/library/x4d2c09s(v=VS.120).aspx

vcvarsall.batの位置は、"C:\VBインストール先\Microsoft Visual Studio 14.0\VC" にあり、コマンドプロンプトから叩けばいいだけです。

ただそこから作業場所を移動させるのが面倒くさいので、バッチファイルに書いてしまいましょう。
notepadを開き


@echo off
rem バッチファイルのある場所に移動
cd /d %~dp0
rem 64bitで起動させる
%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"" amd64


と書きます。
そしてそのファイルを「cl64.bat」とでも名前をつけて保存します。
このバッチファイルを作業フォルダにおいておけばそれを叩くだけでその場所をカレントフォルダにした64bit C/C++簡易コンパイラの出来上がりです。

テストソース:
[C]
64test.c

#include <stdio.h>

int main() {


 int *pint;
 int len;

 len = sizeof(pint);
 printf("size = %d\n", len);

 return 0;

}


実行:
> cl 64test.c
> 64test
size: 8


[C++]
64test.cpp

#include <iostream>

int main(void) {

 int *pnum;
 int len;

 len = sizeof(pnum);
 std::cout << "size: " << len << std::endl;

 return 0;

}

実行:
> cl /EHsc 64test.cpp
> 64test
size: 8



間違いなく実行されてsize: 8という結果がでたら64bit用の実行ファイルが出来ています。
通常の開発者コマンドプロンプトは32bit用なのでsize: 4という結果になります。

Windows で簡易的に64bit用のC/C++の実行してみたいときに便利です。

2015年7月12日日曜日

CentOS6にJava8とEclipse Marsの開発環境をつくる

CentOSにJava 8をインストール


Eclipse MarsがリリースされたのでCentOS6にJava環境を作りたいと思います。

環境:
$ cat /etc/redhat-release
CentOS release 6.6 (Final)

$ arch
i686

標準インストールでCentOSを作った人はJava 6と Java 7がすでに入っていると思います。
今回はそれにJava 8を加え開発環境であるEclipse Marsをインストールしたいと思います。

現在のJavaの確認

$ which java
/usr/bin/java

Javaのカレントバージョンの確認

$ java -version
java version "1.7.0_79"
OpenJDK Runtime Environment (rhel-2.5.5.3.el6_6-i386 u79-b14)

$ javac -version
javac 1.6.0_35


OpenJDK 1.8はyumリポジトリにありますが、JavaFxが無いなど若干違うので今回はOracleの公式サイトからrpmパッケージをダウンロードします。
もしOpenJDK 1.8がある場合はぶつかってしまうのでアンインストールしてください。

$ sudo yum remove java-1.8.0-openjdk


JDK 8のダウンロード


Oracleのサイトからrpmをダウンロードします。
Accept License Agreementにチェックを入れ、64bitならLinux x64、32bitならLinux x86をダウンロードしましょう。

そしてパッケージのインストール

 # rpm -ivh jdk-8u45-linux-i586.rpm

で完了です。あっけないほど簡単ですね。
インストールするだけではカレントバージョンは変わらないのでalternativesコマンドでバージョンを変更します。

$ sudo alternatives --config java

4 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk/bin/java
   2           /usr/lib/jvm/jre-1.6.0-openjdk/bin/java
   3           /usr/java/jdk1.8.0_45/jre/bin/java
   4           /usr/lib/jvm/jre-1.5.0-gcj/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:3


同じ要領でjavacのバージョンも変更してください。
どちらも管理者権限を忘れずに。

$ sudo  alternatives --config javac


もう一度Javaのバージョン確認。

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)

$ javac -version
javac 1.8.0_45

変更出来ていますね。

Eclipse Marsのダウンロード

Java環境が整ったら次は開発環境のEclipseの構築です。
Eclipseのサイトから自分の好きな開発環境を選んでください。
今回はJava EEを選びました。


Eclipseは解凍するだけです。

# tar xvzf eclipse-jee-mars-R-linux-gtk.tar.gz

解凍したものは好きな位置に配置します。
今回は/opt配下にeclipseディレクトリを作りました。いくつかのEclipseバージョンをインストールする予定ならバージョンの数字を入れてもいいかもしれません。

# mkdir /opt/eclipse
# mv  eclipse  /opt/eclipse/eclipse45

配置が完成したらeclipseが簡単に起動出来るようにリンクを貼りましょう。

# cd /usr/bin
# ln -s /opt/eclipse/eclipse45  eclipse

これでパスにリンクしたのでeclipse & で簡単に起動できます。

Gnomeアプリケーションへの登録

Gnomeデスクトップを使用している場合はEclipseをGnomeアプリケーションからも起動できるようにデスクトップに登録しましょう。
アプリケーションの登録はdesktopファイルを作るだけで登録できます。
デスクトップエントリファイルを作成し/usr/share/applications/ に配置するだけです。
書式はOracleのサイトに書いてあります。

$ vim eclipse45.desktop

[Desktop Entry]
Version=1.0
Name=Eclipse Mars
Comment=Eclipse Mars for Java EE
Exec=/opt/eclipse/eclipse4.5/eclipse
Icon=/opt/eclipse/eclipse4.5/icon.xpm
Terminal=false
Type=Application
Categories=Development;


間違っていなければデスクトップの「アプリケーション」→「プログラミング」に登録されているでしょう。

2015年7月10日金曜日

PHPのdateのdefalt timezone set Warnig

PHPでのDate Warning


PHP環境を構築してdate関係の関数を使うとこんなふうな警告を受けることが有ります。

 It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier.

これは書いてあるとおり、date.timezoneの設定がされていないということです。システムから読み込んで使う時刻は安全でないので、php.iniに運用する場所のtimezoneを設定してください。

phpinfo()関数でphp.iniのパスとdate.timezoneが設定されているか確認して下さい。


; Defines the default timezone used by the date functions
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
; date.timezone =

になっている部分を

; Defines the default timezone used by the date functions
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
date.timezone = "Asia/Tokyo"

に変えてサーバーをrestart

反映されて警告が出なければ成功です。

CLIでもDate Warningが出る場合


CLIの呼び出すPHP環境が違うものを使っているかもしれません。
CLIの環境は以下のコマンドで確かめられます。

# php --ini

Loaded Configuration File:  というのがCLI版php.iniの場所です。




2015年7月2日木曜日

Atomのキーマップの重複

Atomのkeymap

Atomは便利なパッケージが多くあるのでパッケージをどんどん入れるとショートカットキーが効かなくなる場合があります。原因はキーマップの重複だったりします。

[ctrl-.]で現在どのショートカットキーが使われているか調べられます。
そしてSettingsのKeybindingsで目的のショートカットキーを打つと重複しているか調べられます。
コントロールキーは[ctrl]、シフトキーは[shift]、オルトキーは[alt]で同時押しをハイフンで繋ぎます。
たとえばコントロールキー+eなら[ctrl-E]と打ちます。
KeystrokeとSelectorが同じ場合は重複しており一つしか使われません。


キーマップが重複する場合はキーマップファイルを編集してみましょう。
Atomにはデフォルトのキーマップとパッケージごとのキーマップ、それにユーザーが自由に設定できるキーマップが存在します。
デフォルトはソースに書いてあるようなので基本的に編集はできません。*1
パッケージのキーマップはそれぞれのパッケージの設定ファイルにあるのでそれを編集すれば変更できます。ユーザーの設定ファイルはWindowsならC:\Users\ユーザ名\.atom\keymap.csonです。そこで既存のキーマップに対しオーバーライドで変更が可能です。

scon形式で書かれており、テキストエディタモードの[ctrl-e]を無効にしたいならunset!を書きます。

 'atom-text-editor':
     'ctrl-e': 'unset!'

基本的にはkeymap.sconを編集でオーバライドすれば良いですが、書式が良くわからない場合はパッケージごとのkeymapsファイルのショートカットキーを編集します。たとえば重複していらない場合はコメントアウトするだけで無効にできます。


場所はC:\Users\ユーザ名\.atom\packages\パッケージ名\keymapsの中。
ただ、パッケージごとのファイルを編集する場合は後で変更点が分かる様にしておいてください。

編集し終わったら再起動して反映されていれば成功です。

*1 デフォルトのキーを無効にしたい場合はabort!で出来る様です。




2015年7月1日水曜日

Atomのテーマ

AtomのTheme


自分が普段手にするテキストエディターでは機能、操作感など様々あると思いますが、その中でも見た目を重視する人も多いのではないでしょうか?

Atomはデフォルトの見た目もクールですが、さらに見やすくするためにテーマを変更するのが常識となっています。

Atomのテーマ変更はUIが素晴らしいためSettings画面から容易に変えられるように出来ています。[File]→[Settings]でテーマを変えてみましょう。


Themeのインストール



SettingsのInstallから好きなテーマを探します。どんなテーマがあるかは公式を見ればよいでしょう。

公式サイトではFeatured(おすすめ)、Trending(最近の流行り)、 Newest(最新の) Recently Updated(最新に更新された)と分けてエントリ-されています。Download数からも人気が推測されます。
自分が気に入ったものでいいと思いますが一つ一つ見るのが面倒なら人気の高いものを使ってみるといいでしょう。

2種類のテーマ



Atomは大きくUI Theme とSyntax Themeの2種類のテーマがあります。それぞれエディタ全体の見た目と文字色など構文のテーマと分かれています。今回は人気のUIにあるSeti UIをSyntaxにMonokaiを入れてみます。


Setiはファイルに応じてアイコンが示されるので分かりやすく人気です。Monokaiは目にやさしいダーク系の配色に見やすい色分けで有名です。どちらもSublime Textから人気でしたね。

Installしたテーマはセレクトメニューで変更出来、その場で変わるので色々変更してみてしっくり来るものに変えてみてください。




2015年6月29日月曜日

Atomエディターをインストールする(Windows)

Atomとは


今話題のAtom。Sublime Textを超えたとも言われるエディターでエンジニアたちはこぞって使い始めています。その美しさと機能はすごいの一言。そのAtomをWindowsにインストールします。
さっそくインストールしてみましょう。

環境:
Windwos 8.1

ますは公式サイトからダウンロードします。Windowsからアクセスすれば直でDownloadボタンがあるので分かりやすいですね。


AtomSetup.exeがダウンロードされますのでクリック。しばらくするとインストール完了です。


完了すればデスクトップにアイコンが出来ます。ものすごく簡単です。簡単過ぎてどこへインストールされたのか分かりません。Window8でのインストール先は
C:\Users\ユーザ名\AppData\Local\atom\app-1.0.0でした。環境設定やファイルの関連付けなどはここを探しましょう。

Sublime Textの様に必要な機能はパッケージとして追加していきます。

フォントの変更

フォントはAtomに個別にインストールするのではなくそのままWindowのシステムのものを使用します。
ですので欲しいフォントがあればまずWindowのフォントに入れてください。今日本のエンジニアに人気があるのRicty Diminishedでしょう。Rictyの問題を解消したフォントです。Linuxでの開発を想定しているようですが視野性が高くWindowsでも有用です。

GitHubからRicty DiminishedのページでDownload ZIPのボタンでダウンロードできます。
解凍すればRictyDiminished-masterというフォルダーが作られますので中のttf拡張子をクリックするとフォントが確認できます。気に入ればインストールボタンを押してインストール。全部入れたい人はまとめて選択し右クリックからインストールするか「コントロールパネル」→「デスクトップのカスタマイズ」→「フォント」の中にttfファイルを入れてください。それが出来たら一度Windowsを再起動してください。



再起動したら、Atomを立ち上げセッティング画面「File」→「Settings」でEditor Settingsの項目まで降ります。

そこでFont Familyのフォームに"Ricty Diminished"とダブルクォートを付けて入力します。ちゃんと反映されればその場で変更されるはずです。反映されない場合は名前が間違っているかダブルクォートをつけていないかWindowsを再起動していないなど原因が考えられます。




2015年6月21日日曜日

CentOSに簡単にHaskell環境を作る

Haskellのインストール

ここ数年の関数型言語の流行でHaskellが注目されています。
Haskellは純粋関数型プログラミング言語で関数の副作用をもたず遅延評価などの機構を備えているおり関数プログラミング言語の本質を学ぶのに適しているからと言われています。
そのHaskellをCentOSで試すために簡単な方法でインストールしたいと思います。

環境
CentOS7


Haskellの環境を構築するには必要なライブラリや処理系、パッケージ管理システムなどが必要になってきます。
それらを一つずつインストールするのも結構ですが、簡単にインストールしたい場合は必要な環境がはじめから揃っているHaskell-Platformをインストールすればいいでしょう。
公式ベージから自分の環境にあったソースを引っ張ってくるのもいいですが、最新バージョンにこだわりが無ければyumでhaskell-platformをインストールしたほうがトラブルがすくないでしょう。

ちなみに標準のリポジトリには入ってないのでepelリポジトリは入れておいてください。

 $ ls /etc/yum.repos.d/
CentOS-Base.repo       epel-testing.repo     epel.repo    remi.repo

$ yum --enablerepo=epel info haskell-platform
名前                : haskell-platform
アーキテクチャー    : x86_64
バージョン          : 2013.2.0.0
リリース            : 36.el7
容量                : 1.4 k
リポジトリー        : installed
提供元リポジトリー  : epel

$ sudo yum --enablerepo=epel install haskell-platform

結構、関連ライブラリが多いです。

さらにグループパッケージでhaskellのパッケージがありますが

$ yum --enablerepo=epel groupinfo haskell
 標準パッケージ:
   =darcs
   =ghc
   =ghc-rpm-macros
   =haskell-platform
   =hscolour
 条件付パッケージ:
   -ghc-gtk-devel

上のパッケージも必要だと思う人はこちらでもいいでしょう。

$ sudo yum --enablerepo=epel groupinstall haskell

インストールできたか確認
処理系GHC

ghc  --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3

パッケージの確認

$ ghc-pkg list
/usr/lib64/ghc-7.6.3/package.conf.d
   Cabal-1.16.0
   GLURaw-1.3.0.0
   GLUT-2.4.0.0
   HTTP-4000.2.8
   HUnit-1.2.5.2
   OpenGL-2.8.0.0
   OpenGLRaw-1.3.0.0
   QuickCheck-2.6


パッケージの更新

$ cabal --version
cabal-install version 1.16.0.2
$ cabal update











2015年6月16日火曜日

nvmでnode管理

nvmのインストール

nvmは進化の早いnode.jsをバージョン管理するための仮想システムのこと。
nvmを使用することによって異なるバージョンでの開発が可能となります。

環境
OS: ContOS7 (Linux)

準備するもの
git

まずgitからnvmをインストールする。

$ git clone https//github.com/creationix/nvm.git ~/.nvm

使用するにはsourceでスクリプトを走らせる

$ source ~/.nvm/nvm.sh

これだけで使用可能

$ nvm --version
0.25.4

インストールできるnode.js一覧を見る

$ nvm ls-remote
        v0.1.14
        v0.1.15
        v0.1.16
        v0.1.17
         
その中からインストールするnode.jsを指定

$ nvm install v0.10.36

端数を折るとその最新バージョンがインストールされる

$ nvm install v0.12

インストールされたバージョンを確認

$ nvm ls
          v0.10.36
->         v0.12.4

->が現在の使用バージョンです。

$ node -v
v0.12.4

$ nvm current
v0.12.4

node.jsバージョンの切り替え

$ nvm use v0.10.36
Now using node v0.10.38 (npm v1.4.26)

起動時にnvmを有効化しnode.jsを指定するには.bash_profileをにコマンドを書きます。

source ~/.nvm/nvm.sh
nvm use 0.10





















2015年1月24日土曜日

pythonzとvirtualenvでPythonの複数バージョン共存の環境構築

Pythonの進化

Pythonは今現在も進化しており、バージョンによってかなり違ってきます。
特にPython 3は根本から見直されており、Python 2から大幅に変更されています。
ですからスクリプトをテストするにもどのバージョンで動くのかは重要になってきます。

新規で作るなら新しいほうが将来性があるのですが、古いバージョンで確かめなければならない時もあり、一様に新しければ良いと言うものでもありません。

そこで一つのシステムで複数バージョンの共有環境を作ります。

複数バージョンの共有

複数バージョンの共有は単純にフォルダを分けてもできないことはないのですが、ライブラリや管理ツールなどどこで何に依存しているかわからなくなってしまうためここは、複数バージョンを分離してインストール出来るpythonzとPythonを仮想化して動かせるvirtualenvを使用して複数バージョンを安全に管理したいと思います。

現在のシステム環境:

カーネル: Linux
カーネルバージョン: 3.10.0-123.el7.x86_64
ディストリビューション: CentOS 7
システムのPythonバージョン: 2.7.5

virtualenvをインストール

まずvirtualenvをpipでインストール
pipが入ってない人はyumかeasy_installで入れてください。

$ sudo easy_install pip
$ sudo pip install virtualenv

ついでにvirtualenvwrapperというvirtualenvを便利に使うためのツールもインストールします。
$ sudo pip install virtualenvwrapper


シェルのスタートアップファイルに以下を追記します。
$ vi ~/.bashrc

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/Devel 
source /usr/bin/virtualenvwrapper.sh

WORKON_HOMEはそのディレクトリに仮想環境が構築されるという意味です。
PROJECT_HOMEはプロジェクトを作成するときに使用します。
virtualenvwrapperの位置は環境に依存します。

$ which virtualenvwrapper.sh

で位置をたしかめてください。
シェルに反映させてバージョン確認ができれば成功です。

$ virtualenv --version
12.0.5

pythonzのインストール

pythonzはシステムのPythonを元に構築されるのでシステムに2.6以上のPythonと開発ツール、以下の開発ライブラリが必要です。
$ sudo yum groupinstall "Development tools"

zlib-devel bzip2-devel openssl-devel readline-devel ncurses-devel sqlite-devel gdbm-devel db4-devel expat-devel libpcap-devel xz-devel pcre-devel

CentOS 7では以下のライブラリが足りなかったので追加してからpythonzのインストールを行います。
$ sudo yum install zlib-devel openssl-devel

pythonzのインストール
$ curl -kL https://raw.github.com/saghul/pythonz/master/pythonz-install | bash

~/.bashrcに以下を書き込み
[[ -s $HOME/.pythonz/etc/bashrc ]] && source $HOME/.pythonz/etc/bashrc

以上でpythonzがhome配下にインストールされますが、PYTHONZ_ROOT=パス のオプションで任意の場所にインストールできます。
ちなみに環境変数は/etc/profile.d/pythonz.sh に書き込まれます。

インストールの確認
$ pythonz version
1.7.0

バージョン別のPythonをインストールするにはバージョンを指定するだけです。
インストール出来るバージョンは以下のコマンドで確認して下さい。
$ pythonz list -a

次は2.7.9 と 3.4.2のバージョンを取り込む例です。
$ pythonz install 2.7.9 3.4.2

少し時間がかかりますがInstalled CPython-(version) successfully.と出れば成功です。
$ pythonz list
# Installed Python versions
  CPython-2.7.9
  CPython-3.4.2
さて環境は整いましたのでPythonの仮想実行環境を作成しましょう。
mkvirtualenvコマンドで作成しま
-pオプションで使用するバージョンのPythonのパスを、その後ろに作成する仮想環境のディレクトリ名を指定します今回は分かりやすいpython27 python34としました。
&& deactivateは作成すると自動的に仮想環境内に入るため作成のみの場合はdeactivateを指定します。

$ mkvirtualenv -p ~/.pythonz/pythons/CPython-2.7.9/bin/python python27 && deactivate
$ mkvirtualenv -p ~/.pythonz/pythons/CPython-3.4.2/bin/python python34 && deactivate

$ workon
python27
python34

workonコマンドで作成された仮想環境を表示します。

では仮想環境内に入ってみましょう。
作られた仮想環境はWORKON_HOMEに指定された場所にあります。
$ ls .virtualenvs/
get_env_details  postdeactivate    postrmvirtualenv  premkproject     python27
initialize       postmkproject     preactivate       premkvirtualenv  python34
postactivate     postmkvirtualenv  predeactivate     prermvirtualenv
$ cd .virtualenvs/python34
$ ls
bin  include  lib

$ source bin/activate
(python34) $ 
$ python --version
Python 3.4.2
仮想環境へはsource コマンドでbinにあるactivateを反映させることで仮想環境内に入ることができます。入っていればシェルプロンプトの前に(仮想環境名)が表示されています。
versionを確かめてみれば確かにシステムと違うバージョンになっています。

これで通常の環境と同じようなPython仮想環境が作成できました。
deactivateコマンドでいつでも仮想環境から抜け出せます。

$ deactivate
$ python --version
Python 2.7.5




2015年1月18日日曜日

CentOS7にChromeを入れる

CentOS7をworkstationとして使用した場合にブラウザなどの環境を用意してwebアプリの開発に使用したりするでしょう。

そこでCentOS7にChromeをインストールしたいと思います。

Chromeは標準のリポジトリには含まれいないのでGoogleのリポジトリを追加します。
Chromeがあるリポジトリは度々場所が変わるのでいつの間にか使えなくなっている場合もあります。
現時点では以下のURL

[google-chrome]
name=google-chrome baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub


上記の内容を以下の場所に作成
# vim /etc/yum.repos.d/google-chrome.repo


登録出来たらyumでインストールできます。
# yum install google-chrome-stable
or
# yum install google-chrome-beta



確認できれば完成
$ google-chrome --version
Google Chrome 40.0.2214.85 beta










2015年1月12日月曜日

Fedora21の初期設定

 新しいFedora21はCloud、Server、Workstationの3エディションに別れより専門的になりました。
 開発者向けに自分で試すのでWorkstationをインストールしました。
まずは[端末]呼び出しを簡単にするためアクティビティに追加するため
端末は[アクティビティ]の一番下にある[アプリケーションを表示する]➙[ユーティリティ]➙[端末]を右クリック➙[お気に入りに追加]で追加できます。

さらに簡単に呼び出すためにショートカットキーを割り当てます。
[アクティビティ]➙[アプリケーションを表示する]➙[設定]➙[キーボード]➙[ショートカット] タブから[独自のショートカット]を選択し、名前と呼び出しコマンドを入力して設定したいショートカットキーを押せば完成です。
端末の呼び出しコマンドは「gnome-terminal」です。名前とキーは好きなものを設定してください。


日本語環境でインストールするとアイコンなどが日本語で使えて便利なのですが、ホームディレクトリが日本語だとterminalで操作するときに面倒です。
ですのでディレクトリは英語に変換しましょう。

$ LANG=C xdg-user-dirs-gtk-update

ダイアログが出るので更新の方のボタンを押して完了です。

メインユーザのsudo許可
インストール時にrootと一般ユーザ(メインユーザ)を作成すると思うのですが、初期設定でメインユーザはsudoの許可がありません。ですのでsudoが使えるように設定します。

root ALL=(ALL) ALL
ユーザ名 ALL=(ALL) ALL

以下が一番簡単な設定ですが、sudoに変更できるグループを作成してそのメンバーに所属させる方法でも良いかもしれません。

開発環境の整備

初期設定でgccなど開発ツールを入れていない場合はyumで追加します。
yumのgroupinstallを使用するとまとめてインストールできます。

$ yum grouplist

で開発ツールがあるか確認します。

$yum groupinstall "開発ツール"

日本語環境だと名前も日本語なのはちょっと違和感あります。
中身に何が有るかはgroupinfoで調べられます。

$ yum groupinfo "開発ツール"












2015年1月3日土曜日

Fedoea20にnode.jsをインストールする

Fedora 20にサーバーサイドJavaScript環境を作るnode.jsをインストールします。
以前はRedhat系にnode.jsをインストールするにはソースからビルドする必要があったのですが、今はyumパッケージが提供されているのでそれを利用して簡単にインストールできます。CentOSもepelで提供されています。

yumでnode.jsとnpmの提供確認

$ yum info nodejs
利用可能なパッケージ
名前                : nodejs
アーキテクチャー    : i686
バージョン          : 0.10.33
リリース            : 1.fc20
容量                : 514 k
リポジトリー        : updates/20/x86_64
要約                : JavaScript runtime
URL                 : http://nodejs.org/

$ yum info npm
利用可能なパッケージ
名前                : npm
アーキテクチャー    : noarch
バージョン          : 1.3.6
リリース            : 5.fc20
容量                : 995 k
リポジトリー        : installed
提供元リポジトリー  : updates
要約                : Node.js Package Manager
URL                 : http://npmjs.org/

バージョンも公式が0.10.35だったので最新に近いものが提供されていました。
因みにnode.jsとnodeは別物なので気をつけてください。

# yum install nodejs npm

$ node -v
$ npm -v

で表示されたら成功です。




2015年1月1日木曜日

Fedora 20にvimの環境を整える

vim-enhanced

Fedora 20でのデフォルトのvimはminimal版でvimを便利に使用したい人には物足りない。 そこでvimの強化版vim-enhancedをインストールします。

 まず、自分のvimを確認。

$ rpm -qa vim*
vim-minimal-7.4.475-2.fc20.x86_64

 vim-enhancedをインストール

 $ sudo yum -y install vim-enhanced

 vim-enhancedが確認できたら成功

 $ rpm -qa vim*
vim-common-7.4.475-2.fc20.x86_64
vim-minimal-7.4.475-2.fc20.x86_64
vim-enhanced-7.4.475-2.fc20.x86_64
vim-filesystem-7.4.475-2.fc20.x86_64

vimの環境設定

vimの共通環境は/etc/vimrc、個別設定は~/.vimrcに設定されています。
内容を見ながら自分に合うような環境に変更してください。