コピペコードで快適生活

明日使えるソースを自分のために

VirtualBoxのゲストOS(CentOS)に複数の固定IPを設定する

表題の件の作業メモです。
ネットワークの割当は[ブリッジアダプター]を想定。

作業前:
eth8 に 192.168.135.224 を割り当て

作業後:
eth8 に 192.168.135.224 を割当
eth9 に 192.168.135.225 を割当

アダプターを増やす

VirtualBoxの設定 > ネットワーク でアダプター2を有効化。
それぞれ割当を[ブリッジアダプター]にします。

次にCentOSを起動しrootでログインし、
ifconfigでネットワークアダプタが増えていることを確認します。

eth8      Link encap:Ethernet  HWaddr 08:00:27:9F:8E:30
          inet addr:192.168.135.224  Bcast:192.168.135.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe9f:8e30/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2466 errors:0 dropped:0 overruns:0 frame:0
          TX packets:467 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:232580 (227.1 KiB)  TX bytes:62891 (61.4 KiB)

eth9      Link encap:Ethernet  HWaddr 08:00:27:5C:87:BF
          inet addr:192.168.135.71  Bcast:192.168.135.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe5c:87bf/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2185 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:218982 (213.8 KiB)  TX bytes:1152 (1.1 KiB)
増やしたアダプターにIPアドレスを割当

既に存在するeth8の設定をコピーします。

# cd /etc/sysconfig/network-scripts/
# cp ifcfg-eth8 ifcfg-eth9

ifcfg-eth9を編集します。

TYPE=Ethernet
BOOTPROTO=none
IPADDR=192.168.135.225                    # IPアドレス書き換え
PREFIX=24
GATEWAY=192.168.135.1
DNS1=192.168.135.1
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="eth9"                               # 名前変える
UUID=ecc2e8f6-81b0-4e04-ae26-6ece18645648 # UUIDは下一桁を1ずらすなど別の値に調整
ONBOOT=yes
HWADDR=08:00:27:5C:87:BF                  # VirtualBox > 設定 > ネットワーク > アダプター2 で確認できる MACアドレスを記載
LAST_CONNECT=1426591352
設定を反映

下記コマンドで設定を反映します。

# service network restart
インターフェース eth8 を終了中:  デバイスの状態: 3 (切断済み)
                                                           [  OK  ]
インターフェース eth9 を終了中:  デバイスの状態: 3 (切断済み)
                                                           [  OK  ]
ループバックインターフェースを終了中                       [  OK  ]
ループバックインターフェイスを呼び込み中                   [  OK  ]
インターフェース eth8 を活性化中:  アクティブ接続の状態: アクティベート済み
アクティブ接続のパス: /org/freedesktop/NetworkManager/ActiveConnection/3
                                                           [  OK  ]
インターフェース eth9 を活性化中:  アクティブ接続の状態: アクティベート済み
アクティブ接続のパス: /org/freedesktop/NetworkManager/ActiveConnection/4
                                                           [  OK  ]
確認

ifconfigで設定が反映されていることを確認しておわり。

# ifconfig
eth8      Link encap:Ethernet  HWaddr 08:00:27:9F:8E:30
          inet addr:192.168.135.224  Bcast:192.168.135.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe9f:8e30/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4727 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1167 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:431732 (421.6 KiB)  TX bytes:164535 (160.6 KiB)

eth9      Link encap:Ethernet  HWaddr 08:00:27:5C:87:BF
          inet addr:192.168.135.225  Bcast:192.168.135.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe5c:87bf/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3529 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:349928 (341.7 KiB)  TX bytes:1152 (1.1 KiB)

UPDATE文でLEFT JOIN

SQL力が不足していて、LEFT JOINしたテーブルの値でUPDATEしたいときのやり方がわからなかったのでメモ。

# 確認用
SELECT * FROM users 
LEFT JOIN stores ON stores.id = users.store_id 
WHERE 
stores.company_id != users.copany_id; 

# UPDATE文
UPDATE users
lEFT JOIN stores on stores.id = users.store_id 
SET users.company_id = stores.company_id 
WHERE stores.company_id != users.copany_id; 

闇が深いDB設計になっているのは気にしない。

こちら参考にさせていただきました!感謝です!
mysqlでjoinした結果をupdate - Qiita

RailsのArelの使い方

RailsでArelを使うときは、下記サイトをいつも参照させていただいていましたが、自分メモ用として転載します。
メモ || Arelのwhere系メソッド一覧 User.w...

User.where(User.arel_table[:name].eq("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = 'aa'

User.where(User.arel_table[:name].eq(nil)).to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" IS NULL

User.where(User.arel_table[:name].eq_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" = 'aa' AND "users"."name" = 'bb'))

User.where(User.arel_table[:name].eq_all(["aa",nil])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" = 'aa' AND "users"."name" IS NULL))

User.where(User.arel_table[:name].eq_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" = 'aa' OR "users"."name" = 'bb'))

User.where(User.arel_table[:name].eq_any(["aa",nil])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" = 'aa' OR "users"."name" IS NULL))

User.where(User.arel_table[:name].not_eq("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" != 'aa')

User.where(User.arel_table[:name].not_eq(nil)).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" IS NOT NULL)

User.where(User.arel_table[:name].not_eq_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" != 'aa' AND "users"."name" != 'bb'))

User.where(User.arel_table[:name].not_eq_all(["aa",nil])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" != 'aa' AND "users"."name" IS NOT NULL))

User.where(User.arel_table[:name].not_eq_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" != 'aa' OR "users"."name" != 'bb'))

User.where(User.arel_table[:name].not_eq_any(["aa",nil])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" != 'aa' OR "users"."name" IS NOT NULL))


User.where(User.arel_table[:name].gt("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" > 'aa')

User.where(User.arel_table[:name].gt_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" > 'aa' AND "users"."name" > 'bb'))

User.where(User.arel_table[:name].gt_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" > 'aa' OR "users"."name" > 'bb'))

User.where(User.arel_table[:name].gteq("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" >= 'aa')

User.where(User.arel_table[:name].gteq_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" >= 'aa' AND "users"."name" >= 'bb'))

User.where(User.arel_table[:name].gteq_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" >= 'aa' OR "users"."name" >= 'bb'))


User.where(User.arel_table[:name].lt("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" < 'aa')

User.where(User.arel_table[:name].lt_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" < 'aa' AND "users"."name" < 'bb'))

User.where(User.arel_table[:name].lt_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" < 'aa' OR "users"."name" < 'bb'))

User.where(User.arel_table[:name].lteq("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" <= 'aa')

User.where(User.arel_table[:name].lteq_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" <= 'aa' AND "users"."name" <= 'bb'))

User.where(User.arel_table[:name].lteq_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" <= 'aa' OR "users"."name" <= 'bb'))


User.where(User.arel_table[:name].in(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" IN ('aa', 'bb')

User.where(User.arel_table[:birthday].in('1980-01-01'.to_date..'1990-12-31'.to_date)).to_sql
# => SELECT "users".* FROM "users" WHERE "users"."birthday" BETWEEN '1980-01-01' AND '1990-12-31'

User.where(User.arel_table[:name].in_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" IN ('aa') AND "users"."name" IN ('bb')))

User.where(User.arel_table[:name].in_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" IN ('aa') OR "users"."name" IN ('bb')))

User.where(User.arel_table[:name].not_in(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" NOT IN ('aa', 'bb'))

User.where(User.arel_table[:name].not_in_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" NOT IN ('aa') AND "users"."name" NOT IN ('bb')))

User.where(User.arel_table[:name].not_in_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" NOT IN ('aa') OR "users"."name" NOT IN ('bb')))


User.where(User.arel_table[:name].matches("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" LIKE 'aa')

User.where(User.arel_table[:name].matches("%aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" LIKE '%aa')

User.where(User.arel_table[:name].matches_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" LIKE 'aa' AND "users"."name" LIKE 'bb'))

User.where(User.arel_table[:name].matches_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" LIKE 'aa' OR "users"."name" LIKE 'bb'))

User.where(User.arel_table[:name].does_not_match("aa")).to_sql
# => SELECT "users".* FROM "users" WHERE ("users"."name" NOT LIKE 'aa')

User.where(User.arel_table[:name].does_not_match_all(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" NOT LIKE 'aa' AND "users"."name" NOT LIKE 'bb'))

User.where(User.arel_table[:name].does_not_match_any(["aa","bb"])).to_sql
# => SELECT "users".* FROM "users" WHERE (("users"."name" NOT LIKE 'aa' OR "users"."name" NOT LIKE 'bb'))

受託開発で炎上しないためのチェックリスト

未来への自分の戒めとして「受託開発で炎上しないためのチェックリスト」を作成してみました。基本的なことばかりだけど、この基本をきちんと押さえておくことが大切だと思うのです。

・プロジェクトリーダーを立てているか
・リードエンジニア(技術責任者)を立てているか

・スケジュールを立てているか
・スケジュールに予備日を設けているか
・進捗状況を把握できているか
・遅れに対する対策を講じているか

・メンバーとスケジュール共有したか
・メンバーに担当タスクと期限日を認識させたか
・メンバーと定期的に状況共有しているか

・お客様とスケジュール共有したか
・お客様にお客様担当タスクと期限日を認識させたか
・定期的にお客様に状況を報告しているか

仕様書/設計書を作成したか
仕様書/設計書のレビューを行っているか
仕様書の内容についてお客様と認識合わせしたか
・仕様/設計FIXしたか

・コードレビューを行っているか
 (レビューポイントはリーダブルか/DRYか/再利用しやすいか/拡張しやすいか)

・テスト仕様書/テストコードを作成したか
・テスト仕様書/テストコードのレビューを行っているか

検収時の指摘事項に対する対応として、やる/やらない/別見積を明確にお客様に提示しているか
検収完了の連絡をいただいたか

minttyのカッコいい設定

minttyは設定次第でカッコいい見た目になるのでとても気に入っています。
僕の.minttyrcは↓のような感じです。

BoldAsFont=no
FontHeight=11
Font=Inconsolata
FontIsBold=no
BackgroundColour=0,0,0
ForegroundColour=245,245,245
Transparency=medium
Columns=160
Rows=40
Black=0,0,0
Red=255,204,153
Green=204,255,204
Yellow=255,255,153
Blue=153,204,255
Magenta=204,153,255
Cyan=204,255,255
White=255,255,255
BoldRed=255,204,153
BoldGreen=204,255,204
BoldYellow=255,255,153
BoldBlue=153,204,255
BoldMagenta=204,153,255
BoldCyan=204,255,255
BoldWhite=255,255,255
CopyOnSelect=no


見た目こんな感じになります。
f:id:comb_8107:20160323151424p:plain


設定はこちらを参考にさせていただきました。感謝です。
Cygwin Terminal (Mintty) の設定 - 計算物理屋の研究備忘録


フォントはこちらを使用しています。
Inconsolata

RubyでUTF-8変換時にUndefinedConversionが出た件

shift_jisで書かれたCSVUTF-8に変換して取り込み処理をするところで、Encoding::UndefinedConversionError が吐かれてた。

str.encode('utf-8', 'shift_jis') # => Encoding::UndefinedConversionError: "\x87@" from Shift_JIS to UTF-8


なんでだと思って調べてたところ、shift_jisでは対応していない①とか㈱とかの機種依存文字を変換しようとしていたからエラー出ていたみたい。なのでCP932(Windows-31J)使えば解決。

str.encode('utf-8', 'CP932') # => ①㈱

対応しない文字を強制的に置き換えするときは

str.encode("Shift_JIS", "UTF-8", {
            :invalid => :replace,
            :undef   => :replace,
            :replace => ""})

MySQLのユーザ管理コマンド

ユーザ管理
-- ユーザリスト
SELECT Host, User, Password FROM mysql.user;

-- ユーザ作成
CREATE USER 'kinosuke'@'localhost' IDENTIFIED BY 'some password';

-- ユーザ作成
-- GRANT使う&パスワードハッシュ使う版
GRANT USAGE ON *.* TO 'kinosuke'@'localhost' IDENTIFIED BY PASSWORD '*235FBD5A94312B29D808844FC68009764D01AD27';

-- ユーザ名、ホスト変更
RENAME USER 'kinosuke'@'localhost' TO 'new_name'@'new_host';

-- パスワード変更
SET PASSWORD FOR 'kinosuke'@'localhost' = PASSWORD('some password');

-- ユーザ削除
DROP USER 'kinosuke'@'localhost';
権限変更
-- 権限確認
SHOW GRANTS FOR 'kinosuke'@'localhost';

-- グローバルレベル:
GRANT 権限 ON *.* TO 'kinosuke'@'localhost';

-- データベースレベル:
GRANT 権限 ON db_name.* TO 'kinosuke'@'localhost';

-- テーブルレベル:
GRANT 権限 ON db_name.table_name TO 'kinosuke'@'localhost';

-- カラムレベル:
GRANT 権限 (カラム1, カラム2, ...) ON db_name.table_name TO 'kinosuke'@'localhost';

-- 例) 特定DBのREADのみ
GRANT SELECT ON `mydb`.* TO 'kinosuke'@'localhost';