GRUBとデュアルブートとパーティション
GRUBのインストールと設定について。
DebianとArch Linuxをデュアルブートにしようと思い、
GRUBをどのようにインストールすればいいか調べました。
パーティションは次のようになっています。
/dev/sda MBR /dev/sda1 boot Debian / /dev/sda3 boot Arch / /dev/sda5 Debian Swap /dev/sda6 Arch Swap
【手順】
1. Debianをインストール
2. Debianのインストール時にGRUBをsda(MBR)にインストールした
3. Archのインストール
4. Archのインストール時にGRUBをsda3(Archのroot)にインストールした
このようにインストールすると、起動時にはMBRが読み込まれ、
Debianをインストールする時に入れたGRUBが起動します。
そのため、何も設定をしていない場合は、ArchはGRUBの起動メニューに
表示されないことになります。
したがって次に、ArchがGRUBのメニュリストに表示されるように、
Debianを起動し、/boot/grub/menu.lstの編集を行います。
title Debian GNU/Linux, kernel 2.6.26-2-686 root (hd0,0) kernel /boot/vmlinuz-2.6.26-2-686 root=/dev/sda1 ro quiet initrc /boot/initrc.img-2.6.26-2-686 title Debian GNU/Linux, kernel 2.6.26-2-686 (single-user mode) root (hd0,0) kernel /boot/mvlinuz-2.6.26-2.686 root=/dev/sda2 ro single initrc /boot/initrc.img-2.6.26-2-686 # ここから追加する # Arch Linuxの設定 title Arch Linux root (hd0,2) # chainloaderでロードする # ここを上のDebianと同様に # kernel .. # としてロードするとロードできず失敗する。 # おそくら、パーティションの先頭にGRUBをインストールしているため。 # したがって、GRUBをインストールした場合、 # chainloaderで起動する必要があるよう chainloader +1
Swap領域を作るのには論理パーティションを使いました。
パティションには
* 基本パーティション(基本領域) * 拡張パーティション(拡張領域) * 論理パーティション(論理領域)
があります。
基本パーティションはひとつのディスクにつき4つまで作成できます。
ディスクから直接起動するOSの起動部分はこの基本パーティションに
置かなければいけません。
拡張パーティションはひとつのディスクにひとつのみ作成可能で、
拡張パーティションの中に
論理パーティションを16まで作成できます。
論理領域は必ず連続していなければなりません。
拡張領域を使った場合は、基本領域は3つまでしか作成できなくなります。
ですので、Linuxをインストールするときに手動でパーティションをするとき、
そのパーティションを基本領域にするか、論理領域にするか決めますが、
拡張パーティションにするかどうかの選択がでないのはこのためです。
論理領域にしたら、自動でその論理領域が拡張領域に含まれていると
みなされます。
上の例では
----------------------- MBR /dev/sda MBR ----------------------- 基本領域 /dev/sda1 Debian / ----------------------- 基本領域 /dev/sda3 Arch / ----------------------- 拡張領域 /dev/sda5 Debian Swap /dev/sda6 Arch Swap
となっています。
【Archの疑問点】
ArchLinuxでGRUBをインストールする時、
インストール先として
/dev/sda /dev/sda /dev/sda1 /dev/sda3 /dev/sda5 /dev/sda6
とインストール先が出てきました。
このとき、もしMBRにGRUBをインストールしようとすると
上から二番目の/dev/sdaにインストールしなければいけないようです。
なぜ、上の二つに/dev/sdaと同じものが出てきているのか謎です。。
なんとなく、
https://wiki.archlinux.org/index.php/Beginners%27_Guide#.2Fetc.2Fpacman.d.2Fmirrorlist
のページに書いてある
Warning: Make sure to install GRUB on /dev/sdX and not /dev/sdX#! This is a common mistake.
が関係ある気がしますが、sda#とは書かれていなかったので、どうなっているのか解りません
Xmonadの設定
XFCEからXmonadに乗り換えました!
設定をまとめました。
参考にしたページは
http://haskell.org/haskellwiki/Xmonad/Config_archive/John_Goerzen%27s_Configuration
です。
設定ファイルの説明
メインの設定ファイル ~/.xmonad/xmonad.hs
xmobarrc設定ファイル ~/.xmobarrc
icon trayの設定ファイル ~/.xinitrc
次に各々の設定ファイルを見て行きます。
~/.xmonad/xmonad.hs
-- ~/.xmonad/xmonad.hs import XMonad import XMonad.Hooks.DynamicLog import XMonad.Hooks.ManageDocks import XMonad.Util.Run(spawnPipe) import XMonad.Util.EZConfig(additionalKeys) import System.IO myManageHook = composeAll -- floatさせるアプリケーション [ className =? "Gimp" --> doFloat, -- 次はtildaでなくTildaにしないといけない className =? "Tilda" --> doFloat ] main = do -- .xmobarrcの設定 xmproc <- spawnPipe "/usr/bin/xmobar ~/.xmobarrc" xmonad $ defaultConfig { -- terminalにはxfceのterminalを使う terminal = "terminal", manageHook = manageDocks <+> myManageHook <+> manageHook defaultConfig, layoutHook = avoidStruts $ layoutHook defaultConfig, logHook = dynamicLogWithPP xmobarPP { ppOutput = hPutStrLn xmproc, ppTitle = xmobarColor "green" "" . shorten 50 } -- , modMask = modmask } `additionalKeys` []
~/.xmobarrc
Config { font = "-misc-fixed-*-*-*-*-13-*-*-*-*-*-*-*", bgColor = "black", fgColor = "grey", position = Static { xpos = 0, ypos = 0, width = 1024, height = 20 }, lowerOnStart = True }
~/.xinitrc
#!/bin/sh # # ~/.xinitrc # # Executed by startx (run your window manager from here) # exec gnome-session # exec startkde # exec startxfce4 # ...or the Window Manager of your choice #### #### Setting for Xmonad #### # インプットメソッドの起動 export GTK_IM_MODULE='uim' export QT_IM_MODULE='uim' uim-xim & export XMODIFIERS=@im='uim' uim-toolbar-gtk & # resourceのロード # まだ.Xresourceを使っていないので、ここは未設定 # xrdb -merge .Xresources # icon trayの設定 trayer --edge top --align right --SetDockType true --SetPartialStrut true --expand true --width 10 --transparent true --tint 0x191970 --height 20 & # ccursorの設定 xsetroot -cursor_name left_ptr # 背景の設定 # xsetroot -solid midnightblue # 日本語キーボードの設定 setxkbmap -layout jp ### アプリケーションの起動 # スクリーンセーバの起動 xscreensaver -no-splash & # nm-appletの起動 if [ -x /usr/bin/nm-applet ] ; then nm-applet --sm-disable & fi # gnome-power-managerの起動 if [ -x /usr/bin/gnome-power-manager] ; then gnome-power-manager fi # conkeyの起動 conky & # dropboxの起動 dropboxd & # tildaの起動 tilda & # xmondmapの設定 # この位置で設定しないと失敗する xmodmap ~/.Xmodmap # xmonadを起動する exec xmonad # start xmonad # exec ck-launch-session xmonad
EmacsのSKKの設定
昨日からEmacsでSKKを使い始めました。
キーバインドで悩んだところがあったのでそのメモ
read-onlyのバッファでskkモードをONにしているとき、C-pで上に移動出来ませんでした。
C-p skk-previous-candidate
となっていました。どうやら、skkモードにすることで、マイナーモードのキーバインドになっていたようです。
/usr/share/emacs/site-list/skk/
の下にあるファイルにキーバインドの設定ファイルがあると思われるので、
そのあたりのファイルを探して、キーバインドが
skk-vars.el
に書かれていることがわかりました。
skk-vars.elを
;; 次の行をコメントアウトして ;; (list "x" "\C-p")を(list "x")にする ;; (defcustom skk-previous-candidate-keys (list "x" "\C-p") (defcustom skk-previous-candidate-keys (list "x") "*`skk-previous-candidate' を割当てるキー。 この変数にはキーを表すオブジェクトのリストを指定する。 オブジェクトとしては、キーを表す文字列または event vector が指定できる。" :type (if (get 'key-sequence 'widget-type) '(repeat (key-sequence :tag "キー (C-q key で取得可)")) '(repeat sexp)) :group 'skk-henkan)
と修正しました。
そして、再起動...
うまくいきません。
ここで、ひとつつまづいたのが、バイトコンパイル。
skk-vars.elはすでにバイトコンパイルされているのでM-x byte-compile-fileでバイトコンパイルし直してから、Emacsを再起動することで、
C-p previout-line
となり、キーバインドの修正が出来ました。
bm.el入れました
bm.el入れましたが、ブックマークのセーブ、ロードの設定で少しつまずいたので、そのメモを。
暫定的に、今の設定ファイルはこうなっています。これでうまく動いている状況。
;;; bm.elの設定 ;;; (install-elisp "http://cvs.savannah.gnu.org/viewvc/*checkout*/bm/bm/bm.el") (require 'bm) ;; キーの設定 (global-set-key (kbd "M-@") 'bm-toggle) (global-set-key (kbd "M-[") 'bm-previous) (global-set-key (kbd "M-]") 'bm-next) ;; マークのセーブ (setq-default bm-buffer-persistence t) ;; セーブファイル名の設定 (setq bm-repository-file "~/.emacs.d/.bm-repository") ;; 起動時に設定のロード (setq bm-restore-repository-on-load t) (add-hook 'after-init-hook 'bm-repository-load) (add-hook 'find-file-hooks 'bm-buffer-restore) (add-hook 'after-revert-hook 'bm-buffer-restore) ;; 設定ファイルのセーブ (add-hook 'kill-buffer-hook 'bm-buffer-save) (add-hook 'auto-save-hook 'bm-buffer-save) (add-hook 'after-save-hook 'bm-buffer-save) (add-hook 'vc-before-checkin-hook 'bm-buffer-save) ;; Saving the repository to file when on exit ;; kill-buffer-hook is not called when emacs is killed, so we ;; must save all bookmarks first (add-hook 'kill-emacs-hook '(lambda nil (bm-buffer-save-all) (bm-repository-save)))
この設定は次を参考にさせていただきました。
【ぺっくブログミラー@peccul】
http://d.hatena.ne.jp/peccu/20100402
特に、最後の
;; Saving the repository to file when on exit ;; kill-buffer-hook is not called when emacs is killed, so we ;; must save all bookmarks first (add-hook 'kill-emacs-hook '(lambda nil (bm-buffer-save-all) (bm-repository-save)))
の設定のところはそのままコピーさせていただいています。
HaskellでOAuthとTwitter API
ゴールデンウィークの課題としていたHaskellでOAuth。
jsonの解析はまだ行えていませんが、OAuthを使ってjsonを取得するところまでできたので、その事をまとめます。
TwitterでOAuthを使う基本的な流れについてはtwitter developersのauthenticationの項
http://dev.twitter.com/pages/auth
を見てもらうことにして、ここでは各部分について実際のコードを書きます。
標準で入っていないモジュールがありますので、その際にはcabalなどを使っていれてもらえればと思います。
OAuthを使うのに一番の山場はsignatureの生成です。
僕もここでかなり苦戦しました。
Signatureの生成には次のコードを書きました。
Haskellらしくないコードの書き方かもしれませんが、
どのような手順でSignatureを生成しているのかわかるように書いています。
-- Signature.hs -- signatureを生成する関数を提供するモジュールSignature module Signature ( makeSignature, ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret, URL, Parameter ) where import Data.Word (Word8(..)) import Data.List import Network.HTTP (RequestMethod, urlEncode) -- Base64を使うために次のモジュールをインポートする import qualified Codec.Binary.Base64 as B64 -- HMAC-SHA1を使うために次のモジュールをインポートする import Data.Digest.Pure.SHA (hmacSha1, bytestringDigest, showDigest) import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Lazy.Char8 as L8 type ConsumerKey = String type ConsumerSecret = String type AccessToken = String type AccessTokenSecret = String type URL = String type Parameter = [(String, String)] -- signatureを生成する関数 makeSignature :: URL -> RequestMethod -> ConsumerSecret -> AccessTokenSecret -> Parameter -> String makeSignature url method cSecret aSecret param = str6 where -- keyの作成 key = urlEncode cSecret ++ "&" ++ urlEncode aSecret -- keyを秘密鍵として、signatureBaseStringで作成したsignature base stringのHMAC-SHA1を取得する str4 :: [Word8] str4 = L.unpack $ bytestringDigest $ hmacSha1 (L8.pack key) (L8.pack $ makeSignatureBaseString url method param) -- str4をBase64エンコードする str5 :: String str5 = B64.encode str4 -- str5をURLエンコードする str6 = urlEncode str5 -- signature base stringを生成する関数 makeSignatureBaseString :: URL -> RequestMethod -> Parameter -> String makeSignatureBaseString url method param = str3 where -- メソッド(GET, POST)とURLをエンコードした文字列を"&"で連結する str1 = show method ++ "&" ++ urlEncode url -- paramのキー1=paramの値1&....¶mのキーn=paramの値n -- 【重要】パラメータはソートしておかないといけない str2 = intercalate "&" $ map concatPair (sort param) -- str2をURLエンコードする str2' = urlEncode str2 -- str1とstr2'を"&"で連結する str3 = str1 ++ "&" ++ str2' concatPair :: (String, String) -> String concatPair (x, y) = x ++ "=" ++ y
次にリクエストを作成するコードを書きます。
-- OAuth module module OAuth ( OAuth (..), oauthRequest ) where -- 上で作成したSignatureモジュールのインポート import Signature import Codec.Binary.UTF8.String (encodeString, utf8Encode) import Network.HTTP import Network.URI import Network.HTTP.Proxy (parseProxy) import Network.Browser (browse, request, setProxy, request) import Data.Maybe import Data.List import System.Time (ClockTime(..), getClockTime) import Control.Applicative ((<$>)) import System.Random (randomRIO) -- OAuthデータ型の定義 data OAuth = OAuth { consumerKey :: String, consumerSecret :: String, accessToken :: String, accessTokenSecret :: String } deriving (Show, Eq) -- 乱数の作成 randomInt :: IO Int randomInt = randomRIO (0, maxBound::Int) -- システム時間の取得 getUnixTime :: IO Integer getUnixTime = getUnixTime' <$> getClockTime where getUnixTime' (TOD i _) = i -- oauthを使ってリクエストを作成する関数 oauthRequest :: OAuth -> URL -> RequestMethod -> [(String, String)] -> IO Request_String oauthRequest oauth url method param = do -- 乱数の取得 nonce <- show <$> randomInt -- システム時間の取得 unixTime <- show <$> getUnixTime let -- パラメータをURlエンコードする param' = parameterUrlEncode param -- 次のパラメータもURLエンコードする oauthParam = parameterUrlEncode [("oauth_consumer_key", consumerKey oauth), ("oauth_nonce", nonce), ("oauth_signature_method", "HMAC-SHA1"), ("oauth_timestamp", unixTime), ("oauth_token", accessToken oauth), ("oauth_version", "1.0")] -- Signature.makeSignatureを使ってsignatureを作成する signature = makeSignature url method (consumerSecret oauth) (accessTokenSecret oauth) (param' ++ oauthParam) -- URLに付けるパラメータの作成 urlParam = sort (("oauth_signature", signature): (param' ++ oauthParam)) -- URLの作成 oauthURL = url ++ "?" ++ intercalate "&" (map concatParam urlParam) concatParam :: (String, String) -> String concatParam (x, y) = x ++ "=" ++ y parameterUrlEncode :: [(String, String)] -> [(String, String)] parameterUrlEncode = map $ \(x, y) -> (urlEncode x, urlEncode y) -- リクエストの作成 return $ Request { rqURI = fromJust $ parseURI oauthURL, rqMethod = method, rqHeaders = [], rqBody = "" }
これでリクエストを作成する関数ができたので、実際に使ってみます。
ここでひとつはまったのは、日本語のツイート。
日本語のツイートには、
Codec.Binary.UTF8.String.encodeString
をつかいます。
-- OAuthTwitter.hs module OAuthTwitter where -- 上で作成したモジュールOAuthのインポート import OAuth -- 日本語をツイートするためのUTF8モジュールのインポート import Codec.Binary.UTF8.String (encodeString) import Network.HTTP import Network.HTTP.Proxy (parseProxy) import Network.Browser (browse, request, setProxy, request) import Data.Maybe import Data.List -- user timelineの取得 userTimeline :: OAuth -> [(String, String)] -> IO Request_String userTimeline oauth param = oauthRequest oauth userTimelineURL GET param -- friends timelineの取得 friendsTimeline :: OAuth -> IO Request_String friendsTimeline oauth = do oauthRequest oauth friendsTimelineURL GET [] -- ツイートする update :: OAuth -> String -> IO Request_String update oauth status = oauthRequest oauth updateURL POST [("status", status)] -- リストの取得 listTimeline :: OAuth -> String -> String -> IO Request_String listTimeline oauth userName listName = oauthRequest oauth ("http://api.twitter.com/1/" ++ userName ++ "/lists/" ++ listName ++ "/statuses.json") GET [] -- -- Define URL and oauth for Twitter -- requestTokenURL = "http://api.twitter.com/oauth/request_token" accessTokenURL = "http://api.twitter.com/oauth/access_token" updateURL = "http://api.twitter.com/1/statuses/update.json" userTimelineURL = "http://api.twitter.com/1/statuses/user_timeline.json" friendsTimelineURL = "http://api.twitter.com/1/statuses/friends_timeline.json" cKey = "****" cSecret = "****" aToken = "****" aSecret = "****" oauth = OAuth { consumerKey = cKey, consumerSecret = cSecret, accessToken = aToken, accessTokenSecret = aSecret } main :: IO () main = do -- rq <- userTimeline oauth [("id", "screenName")] -- rq <- friendsTimeline oauth -- 日本語を使うために、encodeStringを使います。 rq <- update oauth $ encodeString "テストツイート" -- rq <- listTimeline oauth "screenName" "listName" (uri, res) <- browse $ do -- プロキシを使うには次をコメントアウトする -- setProxy . fromJust $ parseProxy "proxy.server:8080" request $ rq putStrLn $ rspBody res
参考にしたページは、
【twitter developers Authentication】
http://dev.twitter.com/pages/auth
【EAGLE雑記】
http://d.hatena.ne.jp/eagletmt/20100820/1282253083
です。
あと、OAuthを理解、実装するにあたって、次の本が大変参考になりました。
- 作者: 辻村浩
- 出版社/メーカー: ワークスコーポレーション
- 発売日: 2010/04/21
- メディア: 単行本
- 購入: 4人 クリック: 501回
- この商品を含むブログ (30件) を見る
HaskellでHTTP
HaskellでHTTP!!ということでやってみました。
具体的には、指定先のHTMLを取得してきます。
サンプルコードです。
import Network.HTTP import Network.HTTP.Proxy (parseProxy) import Network.Browser (browse, request, setProxy, request) import Data.Maybe main :: IO () main = do -- リクエストを送り、レスポンスを取得する。 (uri, res) <- browse $ request $ getRequest "http://google.co.jp" -- レスポンスの表示 putStr $ rspBody res
上のプログラムで使っている主な関数の型は
Network.HTTP getRequest :: String -> Request_String Network.HTTP.Base type Request_String = Request String Network.Browser request :: HStream ty => Request ty -> BrowserAction (HandleStream ty) (URI, Response ty) browse :: BrowserAction conn a -> IO a
プロキシを使う場合には次のようにします。
main :: IO () main = do (uri, res) <- browse $ do -- プロキシを設定してリクエストを送る setProxy . fromJust $ parseProxy "proxy.server:8080" request $ getRequest "http://google.co.jp" putStr $ rspBody res
プロキシ関連の関数の型は次のようになります。
Network.HTTP.Proxy parseProxy :: String -> Maybe Proxy Network.HTTP.Base setProxy :: Proxy -> BrowserAction t ()