2017年12月29日金曜日

CSVの列順番を入れ替える

あまプロではCSVファイルを扱う事が有ります。

先日、列の順番を入れ替える案件が有りましたので、あメログ。

test.csv
a,b,c
a,b,c
というCSVを
a,c,b
a,c,b
に並べ替えたいとします。

方法は色々有るんですが、ワンライナーでさくっと変換したい場合は
paste -d, test.csv test.csv | cut -d, -f1,3,5

echo -e "a,b,c\na,b,c" | sed -e "s/^\(.*\),\(.*\),\(.*\)$/\1,\3,\2/g"

echo -e "a,b,c\na,b,c" | awk 'BEGIN{ FS=","; OFS=",";} { print $1, $3, $2}'
ですかね。
他にも色々方法は有るんですが、私はコマンドの短いpasteで処理しました。
実行速度を取るか、メモリ使用量を取るか、コマンドの短さを取るか、好みのコマンドを取るか、プロジェクト毎の決まりに従うか…等々で色々変わりますので、場合に選って使い分けてます。

2017年12月27日水曜日

SCPを高速化

あまプロではシェルスクリプトを作成する場合が有ります。

先日、scpで大量のファイルをコピーする案件が有りました。
scpとはsshのcpで、暗号化通信コピーのコマンドになります。
サーバ間やリモートローカル間でファイル遣り取りする際に使います。

大変便利なコマンドなんですが、暗号化通信の為に接続時に時間が掛かります。
httpsのサイトも最初の表示に時間が掛かるのと同じです。
内部で公開鍵の交換等を行っている為で、どうしても処理に時間が掛かります。
数十〜数百ファイルなら大した時間ではないですが、これが数千数万になると数時間掛かってしまいます。

ディレクトリ内にファイルが有る場合
scp コピー元 コピー先
scp hoge.jpg username@hostname:/path/to/dir
という風にローカルからリモートへファイルをアップロードします。

シェルスクリプトで大量のファイルをアップロードする場合
ls *.jpg | xargs -i scp {} username@hostname:/path/to/dir
こうなります。

しかし、これだと
scp hoge0.jpg username@hostname:/path/to/dir
scp hoge1.jpg username@hostname:/path/to/dir
scp hoge2.jpg username@hostname:/path/to/dir
scp hoge3.jpg username@hostname:/path/to/dir
 ︙
としている事になり、1ファイルずつ接続切断を繰り返すので非効率です。
この場合、rオプションを追加して、ディレクトリごとアップロードすると高速になります。

scp -r hoge/ username@hostname:/path/to/dir

rオプションを追加する事で、内部ではこんな感じになり、
scp hoge0.jpg hoge1.jpg hoge2.jpg hoge3.jpg username@hostname:/path/to/dir
一回の接続切断にまとめてくれます。

ディレクトリ内の一部ファイルをアップロードしたい場合は
一部ファイルを一時ディレクトリにコピーして、一時ディレクトリごとrオプションで送りましょう。
一時ディレクトリの作成にはmktemp -d temp.XXXを用います。詳しくはmanをご覧下さい。

ファイル数やファイルサイズや帯域に選りますが、今回の案件では5〜6倍程高速化しました。

画像ファイルは既に圧縮済なので無理ですが、テキストファイル等でしたらCオプションを追加する事で圧縮転送も可能です。
転送量低下->高速化となります。

2017年12月26日火曜日

SSHでConnection timed out

あまプロではUbuntuサーバ上でシエルスクリプトを作成する事が有ります。

サーバ間の接続にSSHを使っているんですが、先日ある特定のサーバAからサーバBへログインできなくなってしまいました。
Connection timed out
と表示されて、原因不明…。
他のサーバCやサーバDからはサーバBへいつも通りにログインできるんですが、サーバAからのみタイムアウトが発生します。
何故なんでしょう?

2017年12月22日金曜日

DellのLifecycleController上にUbuntuServerをインストール

あまプロではUbuntuサーバを構築する事が有ります。

今回はデルのPCにウブンツをインストールでハマりましたのであメログ。
DellのサーバにはLifecycleControllerというツールがインストールされています。
このライフサイクルコントローラを経由して各OSをインストールする事になります。

また、最近のPCはUEFIという仕組みが採用されており、従来のBIOSとはちと変わってます。
BIOS版のUbuntuをインストール出来るのですが、そうするとLifecycleControllerから起動出来なくなってしまうので、UEFI版をインストールします。
UbuntuのUEFI版はこちらに有ります。ここから製品名のUbuntuを検索してダウンロードします。

ハマりポイント1
LifecycleControllerを経由せずにUbuntuをインストールする事も出来ますが、そうするとLifecycleControllerからOSを認識出来ず、つまりOSが起動出来なくなりますのでご注意を。
LifecycleControllerを経由してUbuntuをインストールしましょう。

ハマりポイント2
LifecycleControllerのイントールでは何故かUSBメモリが使えません
なので、CDやDVD等の光学メディアにインストーラを書き込みます。

この二つのハマりポイントに気を付ければ、通常通りのインストールになります。

Ubuntuのサーバを構築する場合はUbuntuServerのLTS版をインストールします。
LTSとは長期間(五年)保守される版で、サーバ等の長期間稼働さす場合に適してます。

2017年12月12日火曜日

Postgresqlから外部のデータベースを操作する

あまプロでは、データベースを扱う案件を良く請けます。
先日、PostgreSQLからMySQLを操作する案件に携わりましたので、あメログ。

PostgreSQLからMySQL等の外部のデータベースへ接続するにはForeignDataWrapperという拡張機能を用います。
DBリンクという似た機能も有るのですが、これは外部のPostgreSQLとしか接続出来ません。
FDWであればMySQLだけに限らず、色々なDBへ接続できる様です。詳しくはこちらをご覧下さい。

今回はPostgreSQLからMySQLのlist_db.listsというテーブルに接続してみます。
どちらも同じローカルにインストールしている前提です。
リモートのデータベースに接続する場合は、適宜接続設定を行って下さい。
環境は以下の通り
Ubuntu 17.10
PostgreSQL 9.6.6
MySQL 5.7.20
先ず、MySQL用のFDWをインストールします。
Ubuntu(Debian系)では
sudo apt install postgresql-9.6-mysql-fdw
でインストール可能です。
恐らく他のディストリビューションでもインストール出来る筈です。

以降の操作にはデータベースでの管理者権限が必要です。
使用するユーザに管理者権限が付いてない場合は
GRANT ALL PRIVILEGES ON DATABASE データベース名 TO ユーザ名;
で、権限を付与して下さい。


psqlでPostgreSQL(の権限の付けられたデータベース)へログインします。
拡張機能を作成します。
CREATE EXTENSION mysql_fdw;

サーバを作成します。
CREATE SERVER サーバ名 FOREIGN DATA WRAPPER mysql_fdw OPTIONS ( host 'localhost', port '3306');
サーバ名は(以降の設定でも使うので)解り易い名前にして、ホストやポートは環境に合わせて適宜変更して下さい。

マッピングを作成します。
CREATE USER MAPPING FOR public SERVER サーバ名 OPTIONS ( password '******', username 'ユーザ名');
パスワードとユーザ名はMySQL側のパスワードとユーザ名を指定します。

外部テーブルを作成します。
CREATE FOREIGN TABLE lists ( id int, name text)
 SERVER サーバ名 OPTIONS ( dbname 'list_db', table_name 'lists');
テーブルの列名やデータ型はMySQLのテーブル定義に合わせます。
MySQLの場合は
desc テーブル名;
でテーブル定義が表示されます。
違う列名やデータ型に出来るんかな?
そこは未確認です。ひょっとしたら必要な列だけ取得出来るかも。

以上で設定は終わりです。
SELECT * FROM lists;
UPDATE lists SET name = 'ほげほげ';
こんな感じで、PostgreSQLからMySQLへ対してSQL( のDML)を発行する事が出来ます。

外部のデータベース故に色々と制約は有るのですが、結構便利です。

2017年12月11日月曜日

大量のファイル処理

あまプロではシェルスクリプトを作成する場合が有ります。

先日大量のファイルを操作するシェルスクリプトを作成する事が有りましたのであメログ。

 大量の(五万以上)のファイルをワンライナーで変換し様とした際に遭遇したエラー
.hoge.sh: ls: Argument list too long
引数リストが多過ぎますとな!

スクリプト内では
ls -1 *.jpg | 変換コマンド
というコマンドでファイル一覧を取得してたのですが、これがあきませんでした。
ディレクトリ内に多数(五万以上)の画像ファイルが有るので、*.jpgでフィルタして一覧を取得したかったのですが、 どうやら
ls -1 *.jpg
の内部で大量の引数に対応して無いエラーが発生している様です。
xargsを使ってないんかな?

ちなみにフィルタせずに
ls -1
だと大丈夫…何でやねん

仕方ないので
ls -1 | grep .jpg | 変換コマンド
で回避しました。
因みに引数に使用できる最大文字数は
getconf ARG_MAX
で取得出来ます。

2017年12月5日火曜日

無料のドメインを使ってみました

あまプロではwebサイトの構築をお受けする事が有ります。

先日、無料ドメインのFreenomを使う機会が有りました。
さくらVPSでCDNのCloudFlareを使って画像をキャッシュしたかったのですが、
CloudFlareはサブドメインでは使えないので、トップドメインを取得する必要が有ります。
開発用に一時的なトップドメインが必要でしたので、無料ドメインのFreenomを利用しました。

流れとしては
  1. さくらVPS契約
    ネームサーバの利用申請
  2. Freenom契約
    ネームサーバをさくらVPSのネームサーバで登録
  3. Cloudflare契約
    Cloudflareのネームサーバを割り当てられるので、それをFreenomへ登録
こんな感じです。
ちょっとややこしいですけど、さくらVPS(685円)代のみでCDNの開発環境が構築出来ました。
頑張って他のVPS無料サービスを探したら、無料で出来るかもです。
CDNが良ぇ感じに画像をキャッシュしてくれるので、webサーバの負荷が分散されます。

只、Webサーバを数分でも止めると取得したドメインが削除されてしまいますorz
ほんの10分程度、バッチ処理の為にサービスを落としただけなんですけど、サービスを再起動した時には既に遅し、ドメインが削除されておりました。
Freenomの利用規約に書いてるみたいですが、いきなりサイトが表示されなくなった時は開発環境とはいえ焦りました。
まぁ同じドメインは直ぐに再取得出来るので、問題は無かったです。

さくらVPS+ClouddFlare+Freenomで開発環境。
皆さんもお試しあれ。