Tuesday, January 22, 2013

processes & threads management

在系計中工作站管理很常遇到使用者的程式死在那邊,然後一直咬著工作站的 CPU 不放,因而讓工作站的  loading 飆高

以下是處理方法

1. 先 top / htop 看看是哪個東西佔有高 loading
$ top
$ htop

2. 對該 pid 作 renice
$ sudo renice 19 <pid>

3. 已經死掉的程式就直接 top/htop 裏面 kill 掉吧
$ sudo top

4. 如果是 multi-threading 的程式可能需要把運算資源限在某幾顆 cpu 裏面
$ taskset -pc 8-14 <pid>

5. more information

cpu core 數量

grep -E "^core" /proc/cpuinfo

詳細的 ps
ps amxo user,pgid,tid,pcpu,etime,comm --sort user,pgid

taskset
taskset -pc <pid>
taskset -pc <core list> <pid>

看 tid (for multi-threading porgrams)
 ps mp <pic> o tid



systemd-analyze


Arch 和很多 Linux 都開始逐漸改用 systemd 作為 service 管理,取代舊的 SysV rc scripts 。從 top 可以看到 pid 1 的程式就是 systemd (取代原本 Unix 的 init)

systemd 最大的好處就是可以平行的去把 service 叫起來,這篇要講的是在 optimize 時所使用的 profiling 工具:systemd-analyze

根據 man page :

       systemd-analyze blame prints a list of all running units, ordered by the time they took to initialize.This information may be used to optimize boot-up times. Note that the output might be misleading as the initialization of one service might be slow simply because it waits for the initialization of another service to complete.

       systemd-analyze plot prints an SVG graphic detailing which system services have been started at what time, highlighting the time they spent on initialization.

也就是說,主要用法非常簡單,只要兩個指令:

sudo systemd-analyze blame             # see the detail
sudo systemd-analyze plot > out.svg    # picture

blame 會印出花最多時間的服務。我這邊第一名是 dhcpcd@eth0.service

plot 顧名思義就是畫出精美的圖形:




阿!兇手現身了!


for optimization, you can mask/disable some thing 
sudo systemd mask/disable xxx.service     # mask is the stronger version of disable 


結語:systemd-analyze 是非常方便的 profiling 工具來幫助我們優化調整系統開機流程,以及關掉不必要的 service

Wednesday, January 16, 2013

simple RSS fetcher in Perl


寂寞考,念不下書寫點程式 Orz

把一年前 SA 作業寫過的 RSS feed fetcher 拿出來重刻一次,主要用到這兩個 CPAN modules:

https://metacpan.org/module/XML::Feed
https://metacpan.org/module/WWW::Shorten::TinyURL

可以看得出這一年來 Perl 功力的成長(?) 總之現在寫的比較乾淨了 :P

#!/usr/bin/perl -CDS

use 5.014;

use XML::Feed;
use WWW::Shorten::TinyURL;

# max articles number each feed
use constant THRESHOLD => 5;

# RSS feed urls
my @urls = (
    "http://feeds2.feedburner.com/solidot",
    "http://www.36kr.com/feed",
    "http://pansci.tw/feed",
    "http://blog.gslin.org/feed",
    "https://www.linux.com/rss/feeds.php",
    "http://www.linuxplanet.org/blogs/?feed=rss2",
    "http://perlsphere.net/atom.xml",
    "http://planet.linux.org.tw/atom.xml",
    "http://security-sh3ll.blogspot.com/feeds/posts/default",
    "http://feeds.feedburner.com/TheGeekStuff",
    "http://coolshell.cn/feed",
);

# force to print
$|++;
my $done = 0;
my @data = ();
for my $url (@urls) {
    say "fetching ..." . (sprintf "%2d", int ($done/@urls * 100)) . "%";

    # get RSS Feed via URI
    my $feed = XML::Feed->parse(URI->new($url)) or die XML::Feed->errstr;

    my $count = 0;
    for my $entry ($feed->entries) {
        push @data, [$feed->title, $entry->title, $entry->link];
        $count++;
        last if ($count >= THRESHOLD);
    }
    $done++;
}

say "done!";

for (@data) {
    say "$_->[0] | $_->[1]\n$_->[2]";
    my $short =  makeashorterlink($_->[2]);
    say $short;
    say "============================================";
}

get environment in C

一切都是從這篇有趣的 C-faq 開始

http://c-faq.com/ansi/envp.html

有人問了 main() 的 "the third argument" *env[] 是啥?

一般就會講到這個可怕的歷史

在一般的 Unix 底下,很多人會跟你說,可以用 *env[] 或是 extern const char **environ 去問到

甚至給出了這樣的 code ...


#include <stdio.h>
 
extern const char **environ;
 
int main(int argc, const char *argv[], const char *env[])
{
    int i;
    for (i = 0; env[i]; i++)
        printf("env %02d: %s\n", i, env[i]);
    printf("=========================================\n");
    
    for (i = 0; environ[i]; i++)
        printf("env %02d: %s\n", i, environ[i]);
    printf("=========================================\n");
    
    printf(env==environ? "They are same.\n": "They are different.\n");
    return 0;
}

/* 
Output:


env 00: TMPDIR=/tmp/p0rIMq
env 01: PATH=/usr/local/bin:/usr/bin:/bin
env 02: PWD=/home/oAdQev
env 03: LANG=en_US.UTF-8
env 04: HOME=/home/oAdQev
env 05: SHLVL=0
=========================================
env 00: TMPDIR=/tmp/p0rIMq
env 01: PATH=/usr/local/bin:/usr/bin:/bin
env 02: PWD=/home/oAdQev
env 03: LANG=en_US.UTF-8
env 04: HOME=/home/oAdQev
env 05: SHLVL=0
=========================================
They are same.
*/


去 man 一下 environ (7) 可以看到相關的歷史


根據標準,我們應該使用 getenv 來跟系統要環境變數

以下是 C11 Standard 的節錄:


請參考:
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html#getenv
http://www.cplusplus.com/reference/cstdlib/getenv/


C++ 的 case 也類似,用 std::getenv()
http://en.cppreference.com/w/cpp/utility/program/getenv



更多說明可以看這篇棧溢出:

http://stackoverflow.com/questions/10321435/is-char-envp-as-a-third-argument-to-main-portable



Saturday, January 12, 2013

vim easter eggs

幾個有趣的 vim 彩蛋


Ref. http://vim.wikia.com/wiki/Best_Vim_Tips







生命、宇宙和萬物的答案      (梗如以上影片)                                                               
:help 42

尋找聖杯吧!
:help holy-grail

help!
:help!

修道院(?
:help map-modes

當用戶覺得無聊時
:help UserGettingBored

湯匙
:help spoon

神縮寫
:help showmatch

你需要灌木嘛
:Ni!


Ceci n'est pas une pipe
這不是一個 pipe
:help bar


永遠不要認為自己已經擺脫新手

永遠不要認為自己已經擺脫新手


上大學這一年多,看了一些人的現象、行為算是對自己的一些檢討吧

太多人認為自己不是新手,實際上卻...




某朋友說過:

以為自己會了,但其實不會,這比完全不懂的人更糟,因為他們會跟你爭論那些他們覺得是正確的知識



之前和系上某教授上課戰過一些 C language 的概念也是,雖然他是我的老師,我應該要尊敬他,但是我還是無法讓他將錯誤的觀念知識傳授給他人

戰到後來實在是無法說服頑固的老師,只好拿出 C11 Standard 來塞住他的嘴

當然最後老師灰頭土臉的知道他錯了,也說:"我想這方面的資訊我應該要 update 一下"

這其實是比較好聽的想法,很可惜,那天戰的東西在 ANSI C 一開始就有了 lol





正巧今天是 WebConf 2012 ,不過之前就知道下週還有期末修蘿場,於是就沒報名了



剛剛看噗看到一半,同樣的看到有人發了這樣的噗:

                        剛剛不小心誤闖新手場 = =…




誤入新手場,科科。

當然,聽 Conf 時跑錯場的機會在所難免,很常見好不容易搶到的位子結果該 talk 的主題或是程度和自己差太多。

很常見的思維弊病是看了一些也許比較接近初學者的人後就覺得自己是高手,這顯然是錯誤的。

像我反而會開始檢討,我和身邊這些人的程度也許有差,那是不是因為我自己不夠努力而找不到高手願意學習?或者是因為我自己的程度也跟我身邊的人其實也相差無幾?

真正的高手是深藏不露的,而且他們虛懷若谷,遇到新手會非常熱心且有耐心的指導。像是 freenode 上 #perl 就很多這樣的 hackers ,他們解答疑問,題點我們思路的盲點,或是補足我們知識的不足。這些高手是不會看不起新手的。

有個很好的習慣,常常跑到書店或是圖書館去閱讀,找那些給 Beginners 的書。最基本的練習、最基礎的圖書、最基礎的教材再三而閱讀的話往往能帶給我們有趣的思想。舉個例好了,從去年年初算來寫 Python 也算是寫了一陣子了,最近閱讀的 ThinkPython 就帶給我很大的啟發。愈是給初學者的教材,往往會更用心的編輯,明確指示哪邊該注意、該小心,或是更清楚地說明正確的觀念。

看新手書籍的好處是,可以再三的檢視自己的習慣,是否有一些不錯的 coding style 可以學習,這些都是對於就算是五年十年以上的編程老手還是有可以自我檢討學習的地方吧!



老媽常說一句話:

How do you know you don't know?


我們無法知道那些我們不知道的,我不知道"我其實不知道"。



給自己一點反省 : )



其實會寫這篇文章的原因是看了強者我朋友 __CA__ 和 PkmX 學長在 ptt 某串系列文的關係 :P

Friday, January 11, 2013

二下選課


期末考悲劇之際,又逢強檔上映






結果出爐,一言以蔽之,悲劇...


逃げちゃダメだ。逃げちゃタメだ。逃げちゃダメだ。逃げちゃダメだ。






即使很遺憾還是先報喜吧:

選到了聽說又涼又甜的 彭文志 DB

港仔黃世強 ASM  聽說也不錯 (?

王國禎的網路也好像說很好混...      # 我還是趕快念我的研究所網路期末考好惹不知道能不能直接抵掉



最熱血的是,演算法小黃耶!!!要成功蒐集全套小黃套餐惹嗎XD

基礎程式設計是系統自己選的... 去年早就過惹 o_O 而且只花了半小時不到




接下來是憂的部分:

簡榮宏機率不知道會不會雷,不過我確信我危機噴已經忘光惹  ^q^

陳健 D-lab  聽說也 ...(ry 靠大濕照惹

最令我痛心的是:體育一個都沒上... GG!





最後,我覺得我可以考慮念大五了...

照這樣的人品下去該不會大學四年體育跟通識修不夠吧 QQQQQQQQ

目前為止只累積了通識 X2 跟體育 X2 ...  (畢業門檻:通識 X10. 體育 X6)


想起 新世紀エヴァンゲリオン 裡面經典的台詞...




凌波零:「對不起,在這種時候,我不知道該用什麼表情來面對你。」

碇真嗣:「你只要微笑就可以了。」

Monday, January 7, 2013

change html code highlighter for my blog

原本拿來在 blog 貼 code 的 syntax highlighter http://tohtml.com/ 好像爛掉了...

目前用這個當作替代品,配色可能會有點不習慣,抱歉 <(_ _)>

http://markup.su/highlighter/

update to awesome 3.5

最近 awesome 大改,不過前一陣子有點忙,一直沒有把它升上去

昨天有空 pacman -Syu 然後 reboot 後我的 rc.lua 就爆炸了 XDrz

(其實我幾乎每天都會 Syu 一下,只是不常 reboot)

今天稍微看了一下 release log 就順手改了一下,目前正常工作中 :D

http://awesome.naquadah.org/wiki/Awesome_3.4_to_3.5



簡結一下 3.5 的亮點

LGI (Lua GObject Introspection)

https://github.com/pavouk/lgi dynamic Lua binding to GObject based libraries.

Lua 5.2 Compatibility



設定檔語法部份比較麻煩的地方主要有兩個

Signals
    add_signal => connect_signal
    remove_signal => disconnect_signal.

Widget Library

    textbox Migrated to wibox.widget.textbox()
    imagebox Migrated to wibox.widget.imagebox()
    systray Migrated to wibox.widget.systray()


My rc.lua

https://github.com/xatier/rc-files/blob/master/rc.lua

-- Standard awesome library
local gears = require("gears")
local awful = require("awful")
awful.rules = require("awful.rules")
require("awful.autofocus")
-- Widget and layout library
local wibox = require("wibox")
-- Theme handling library
local beautiful = require("beautiful")
-- Notification library
local naughty = require("naughty")
local menubar = require("menubar")

-- vicious widgets library
local vicious = require("vicious")


-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
if awesome.startup_errors then
    naughty.notify({ preset = naughty.config.presets.critical,
                     title = "Oops, there were errors during startup!",
                     text = awesome.startup_errors })
end

-- Handle runtime errors after startup
do
    local in_error = false
    awesome.connect_signal("debug::error", function (err)
        -- Make sure we don't go into an endless error loop
        if in_error then return end
        in_error = true

        naughty.notify({ preset = naughty.config.presets.critical,
                         title = "Oops, an error happened!",
                         text = err })
        in_error = false
    end)
end
-- }}}

-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
beautiful.init("/home/xatierlike/.config/awesome/themes/default/theme.lua")

-- default terminal and editor
terminal = "urxvt"
editor = os.getenv("EDITOR") or "vim"
editor_cmd = terminal .. " -e " .. editor
-- modkey
modkey = "Mod4"





-- Table of layouts to cover with awful.layout.inc, order matters.
local layouts =
{
    -- delete useless layouts
    awful.layout.suit.tile,               -- 1 (tile.right)
    awful.layout.suit.tile.left,          -- 2
    awful.layout.suit.tile.bottom,        -- 3
    -- awful.layout.suit.tile.top,           -- 
    -- awful.layout.suit.fair,               -- 
    -- awful.layout.suit.fair.horizontal,    -- 
    -- awful.layout.suit.spiral,             -- 
    -- awful.layout.suit.spiral.dwindle,     -- 
    awful.layout.suit.max,                -- 4
    -- awful.layout.suit.max.fullscreen,     --
    -- awful.layout.suit.magnifier,          --
    awful.layout.suit.floating            -- 5
}
-- }}}

-- {{{ Wallpaper
beautiful.wallpaper = "/home/xatierlike/Pictures/goodbye.jpg"
if beautiful.wallpaper then
    for s = 1, screen.count() do
        gears.wallpaper.maximized(beautiful.wallpaper, s, true)
    end
end
-- }}}

-- {{{ Tags
-- Each screen has its own tag table.
tags = {}
for s = 1, screen.count() do
    tags[s] = awful.tag(
        {"⌨", "☠", "☢", "☣", "☮", "✈", "✍", "♺", "(._.?)"},
        s,
        { layouts[2], layouts[2], layouts[2],
          layouts[2], layouts[2], layouts[2],
          layouts[5], layouts[5], layouts[2]
        }
    )
end

-- }}}

-- {{{ Menu
-- Create a laucher widget and a main menu
myawesomemenu = {
   { "manual", terminal .. " -e man awesome" },
   { "edit config", editor_cmd .. " " .. awesome.conffile },
   { "restart", awesome.restart },
   { "quit", awesome.quit }
}

mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
                                    { "open terminal", terminal }
                                  }
                        })

mylauncher = awful.widget.launcher({ image = beautiful.awesome_icon,
                                     menu = mymainmenu })

-- Menubar configuration
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
-- }}}

-- {{{ Wibox

-- network usage
netwidget = wibox.widget.textbox()
vicious.register(netwidget, vicious.widgets.net, '<span color="#CC9090">⇩${eth0 down_kb}</span> <span color="#7F9F7F">⇧${eth0 up_kb}</span>', 3)

-- clock
mytextclock = awful.widget.textclock(" %a %b %d %H:%M:%S ", 1)

-- CPU usage
cpuwidget = wibox.widget.textbox()
vicious.register(cpuwidget, vicious.widgets.cpu, '<span color="#CC0000">$1% </span>[$2:$3:$4:$5]' , 2)

-- memory usage
memwidget = wibox.widget.textbox()
vicious.register(memwidget, vicious.widgets.mem, '$2MB/$3MB (<span color="#00EE00">$1%</span>)', 5)

-- widget separator
separator = wibox.widget.textbox()
separator.text  = " | "

-- Create a wibox for each screen and add it
mywibox = {}
mypromptbox = {}
mylayoutbox = {}
mytaglist = {}
mytaglist.buttons = awful.util.table.join(
                    awful.button({ }, 1, awful.tag.viewonly),
                    awful.button({ modkey }, 1, awful.client.movetotag),
                    awful.button({ }, 3, awful.tag.viewtoggle),
                    awful.button({ modkey }, 3, awful.client.toggletag),
                    awful.button({ }, 4, function(t) awful.tag.viewnext(awful.tag.getscreen(t)) end),
                    awful.button({ }, 5, function(t) awful.tag.viewprev(awful.tag.getscreen(t)) end)
                    )
mytasklist = {}
mytasklist.buttons = awful.util.table.join(
                     awful.button({ }, 1, function (c)
                                              if c == client.focus then
                                                  c.minimized = true
                                              else
                                                  -- Without this, the following
                                                  -- :isvisible() makes no sense
                                                  c.minimized = false
                                                  if not c:isvisible() then
                                                      awful.tag.viewonly(c:tags()[1])
                                                  end
                                                  -- This will also un-minimize
                                                  -- the client, if needed
                                                  client.focus = c
                                                  c:raise()
                                              end
                                          end),
                     awful.button({ }, 3, function ()
                                              if instance then
                                                  instance:hide()
                                                  instance = nil
                                              else
                                                  instance = awful.menu.clients({ width=250 })
                                              end
                                          end),
                     awful.button({ }, 4, function ()
                                              awful.client.focus.byidx(1)
                                              if client.focus then client.focus:raise() end
                                          end),
                     awful.button({ }, 5, function ()
                                              awful.client.focus.byidx(-1)
                                              if client.focus then client.focus:raise() end
                                          end))

for s = 1, screen.count() do
    -- Create a promptbox for each screen
    mypromptbox[s] = awful.widget.prompt()
    -- Create an imagebox widget which will contains an icon indicating which layout we're using.
    -- We need one layoutbox per screen.
    mylayoutbox[s] = awful.widget.layoutbox(s)
    mylayoutbox[s]:buttons(awful.util.table.join(
                           awful.button({ }, 1, function () awful.layout.inc(layouts, 1) end),
                           awful.button({ }, 3, function () awful.layout.inc(layouts, -1) end),
                           awful.button({ }, 4, function () awful.layout.inc(layouts, 1) end),
                           awful.button({ }, 5, function () awful.layout.inc(layouts, -1) end)))
    -- Create a taglist widget
    mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons)

    -- Create a tasklist widget
    mytasklist[s] = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons)

    -- Create the wibox
    mywibox[s] = awful.wibox({ position = "top", screen = s })

    -- Widgets that are aligned to the left
    local left_layout = wibox.layout.fixed.horizontal()
    left_layout:add(mylauncher)
    left_layout:add(mytaglist[s])
    left_layout:add(mypromptbox[s])

    -- Widgets that are aligned to the right
    local right_layout = wibox.layout.fixed.horizontal()

    -- only display systray on screen 1
    if s == 1 then right_layout:add(wibox.widget.systray()) end

    -- add my widgets
    right_layout:add(netwidget)
    right_layout:add(separator)
    right_layout:add(cpuwidget)
    right_layout:add(separator)
    right_layout:add(memwidget)
    right_layout:add(separator)
    right_layout:add(mytextclock)
    right_layout:add(mylayoutbox[s])

    -- Now bring it all together (with the tasklist in the middle)
    local layout = wibox.layout.align.horizontal()
    layout:set_left(left_layout)
    layout:set_middle(mytasklist[s])
    layout:set_right(right_layout)

    mywibox[s]:set_widget(layout)
end
-- }}}

-- {{{ Mouse bindings
root.buttons(awful.util.table.join(
    awful.button({ }, 3, function () mymainmenu:toggle() end),
    awful.button({ }, 4, awful.tag.viewnext),
    awful.button({ }, 5, awful.tag.viewprev)
))
-- }}}

-- {{{ Key bindings
globalkeys = awful.util.table.join(
    awful.key({ modkey,           }, "Left",   awful.tag.viewprev       ),
    awful.key({ modkey,           }, "Right",  awful.tag.viewnext       ),
    awful.key({ modkey,           }, "Escape", awful.tag.history.restore),

    awful.key({ modkey,           }, "j",
        function ()
            awful.client.focus.byidx( 1)
            if client.focus then client.focus:raise() end
        end),
    awful.key({ modkey,           }, "k",
        function ()
            awful.client.focus.byidx(-1)
            if client.focus then client.focus:raise() end
        end),
    awful.key({ modkey,           }, "w", function () mymainmenu:show() end),

    -- Layout manipulation
    -- these two lines are useless for me XD
    -- awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx(  1)    end),
    -- awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx( -1)    end),

    awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
    awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
    awful.key({ modkey,           }, "u", awful.client.urgent.jumpto),
    awful.key({ modkey,           }, "Tab",
        function ()
            awful.client.focus.history.previous()
            if client.focus then
                client.focus:raise()
            end
        end),

    -- Standard program
    -- spawn a new terminal
    awful.key({ modkey,           }, "Return", function () awful.util.spawn(terminal) end),
    awful.key({ modkey, "Control" }, "r", awesome.restart),
    awful.key({ modkey, "Shift"   }, "q", awesome.quit),

    -- resize the client (on the focus)
    awful.key({ modkey,           }, "l",     function () awful.tag.incmwfact( 0.05)    end),
    awful.key({ modkey,           }, "h",     function () awful.tag.incmwfact(-0.05)    end),

    -- what the fuck?
    -- awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1)      end),
    -- awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1)      end),
    -- awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1)         end),
    -- awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1)         end),

    -- change window layouts
    awful.key({ modkey,           }, "space", function () awful.layout.inc(layouts,  1) end),
    awful.key({ modkey, "Shift"   }, "space", function () awful.layout.inc(layouts, -1) end),

    -- i can move and click my mouse with hotkeys!!
    awful.key({ modkey, "Shift"   }, "h", function () local mc = mouse.coords()
                mouse.coords({x = mc.x-15, y = mc.y}) end),
    awful.key({ modkey, "Shift"   }, "j", function () local mc = mouse.coords()
                mouse.coords({x = mc.x, y = mc.y+15}) end),
    awful.key({ modkey, "Shift"   }, "k", function () local mc = mouse.coords()
                mouse.coords({x = mc.x, y = mc.y-15}) end),
    awful.key({ modkey, "Shift"   }, "l", function () local mc = mouse.coords()
                mouse.coords({x = mc.x+15, y = mc.y}) end),
    awful.key({ modkey, "Shift"   }, "u", function () awful.util.spawn("xdotool click 1") end),
    awful.key({ modkey, "Shift"   }, "i", function () awful.util.spawn("xdotool click 3") end),

    -- restore the minimized client
    awful.key({ modkey, "Control" }, "n", awful.client.restore),

    -- Prompt
    awful.key({ modkey },            "r",     function () mypromptbox[mouse.screen]:run() end),

    -- run a piece of lua code
    awful.key({ modkey }, "x",
              function ()
                  awful.prompt.run({ prompt = "Run Lua code: " },
                  mypromptbox[mouse.screen].widget,
                  awful.util.eval, nil,
                  awful.util.getdir("cache") .. "/history_eval")
              end),

    -- Menubar
    awful.key({ modkey }, "p", function() menubar.show() end),

    -- lock my screen
    awful.key({ modkey }, "F12", function () awful.util.spawn("xscreensaver-command -lock") end),

    -- shutter as printscreen tools    http://shutter-project.org/
    awful.key({ }, "Print", function () awful.util.spawn("/opt/shutter/bin/shutter") end)

)

clientkeys = awful.util.table.join(
    awful.key({ modkey,           }, "f",      function (c) c.fullscreen = not c.fullscreen  end),
    awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end),
    awful.key({ modkey, "Control" }, "space",  awful.client.floating.toggle                     ),
    awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
    awful.key({ modkey,           }, "o",      awful.client.movetoscreen                        ),
    awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end),
    awful.key({ modkey,           }, "n",
        function (c)
            -- The client currently has the input focus, so it cannot be
            -- minimized, since minimized clients can't have the focus.
            c.minimized = true
        end),
    awful.key({ modkey,           }, "m",
        function (c)
            c.maximized_horizontal = not c.maximized_horizontal
            c.maximized_vertical   = not c.maximized_vertical
        end)
)

-- Compute the maximum number of digit we need, limited to 9
keynumber = 0
for s = 1, screen.count() do
   keynumber = math.min(9, math.max(#tags[s], keynumber))
end

-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, keynumber do
    globalkeys = awful.util.table.join(globalkeys,
        awful.key({ modkey }, "#" .. i + 9,
                  function ()
                        local screen = mouse.screen
                        if tags[screen][i] then
                            awful.tag.viewonly(tags[screen][i])
                        end
                  end),
        awful.key({ modkey, "Control" }, "#" .. i + 9,
                  function ()
                      local screen = mouse.screen
                      if tags[screen][i] then
                          awful.tag.viewtoggle(tags[screen][i])
                      end
                  end),
        awful.key({ modkey, "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus and tags[client.focus.screen][i] then
                          awful.client.movetotag(tags[client.focus.screen][i])
                      end
                  end),
        awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus and tags[client.focus.screen][i] then
                          awful.client.toggletag(tags[client.focus.screen][i])
                      end
                  end))
end

clientbuttons = awful.util.table.join(
    awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
    awful.button({ modkey }, 1, awful.mouse.client.move),
    awful.button({ modkey }, 3, awful.mouse.client.resize))

-- Set keys
root.keys(globalkeys)
-- }}}

-- {{{ Rules
awful.rules.rules = {
    -- All clients will match this rule.
    { rule = { },
      properties = { border_width = beautiful.border_width,
                     border_color = beautiful.border_normal,
                     focus = awful.client.focus.filter,
                     keys = clientkeys,
                     buttons = clientbuttons } },
    { rule = { class = "MPlayer" },
      properties = { floating = true } },
    { rule = { class = "pinentry" },
      properties = { floating = true } },
    { rule = { class = "gimp" },
      properties = { floating = true } },
}
-- }}}

-- {{{ Signals
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c, startup)
    -- Enable sloppy focus
    c:connect_signal("mouse::enter", function(c)
        if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
            and awful.client.focus.filter(c) then
            client.focus = c
        end
    end)

    if not startup then
        -- Set the windows at the slave,
        -- i.e. put it at the end of others instead of setting it master.
        -- awful.client.setslave(c)

        -- Put windows in a smart way, only if they does not set an initial position.
        if not c.size_hints.user_position and not c.size_hints.program_position then
            awful.placement.no_overlap(c)
            awful.placement.no_offscreen(c)
        end
    end

    local titlebars_enabled = false
    if titlebars_enabled and (c.type == "normal" or c.type == "dialog") then
        -- Widgets that are aligned to the left
        local left_layout = wibox.layout.fixed.horizontal()
        left_layout:add(awful.titlebar.widget.iconwidget(c))

        -- Widgets that are aligned to the right
        local right_layout = wibox.layout.fixed.horizontal()
        right_layout:add(awful.titlebar.widget.floatingbutton(c))
        right_layout:add(awful.titlebar.widget.maximizedbutton(c))
        right_layout:add(awful.titlebar.widget.stickybutton(c))
        right_layout:add(awful.titlebar.widget.ontopbutton(c))
        right_layout:add(awful.titlebar.widget.closebutton(c))

        -- The title goes in the middle
        local title = awful.titlebar.widget.titlewidget(c)
        title:buttons(awful.util.table.join(
                awful.button({ }, 1, function()
                    client.focus = c
                    c:raise()
                    awful.mouse.client.move(c)
                end),
                awful.button({ }, 3, function()
                    client.focus = c
                    c:raise()
                    awful.mouse.client.resize(c)
                end)
                ))

        -- Now bring it all together
        local layout = wibox.layout.align.horizontal()
        layout:set_left(left_layout)
        layout:set_right(right_layout)
        layout:set_middle(title)

        awful.titlebar(c):set_widget(layout)
    end
end)

client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
-- }}}

-- vim:set fdm=marker:


以下是跟 default 的 /etc/xdg/awesome/rc.lua 的 diff



更動的地方如下:

vicious widgets
using urxvt and vim as default
delete useless layouts
define my wallpaper
cool tag names
move and click my mouse with keyboard hotkeys
xscreen-saver to lock the screen
shutter-porject as printscreentools




13a14,17
> -- vicious widgets library
> local vicious = require("vicious")
> 
> 
41c45
< beautiful.init("/usr/share/awesome/themes/default/theme.lua")
---
> beautiful.init("/home/xatierlike/.config/awesome/themes/default/theme.lua")
43,45c47,49
< -- This is used later as the default terminal and editor to run.
< terminal = "xterm"
< editor = os.getenv("EDITOR") or "nano"
---
> -- default terminal and editor
> terminal = "urxvt"
> editor = os.getenv("EDITOR") or "vim"
47,52c51
< 
< -- Default modkey.
< -- Usually, Mod4 is the key with a logo between Control and Alt.
< -- If you do not like this or do not have such a key,
< -- I suggest you to remap Mod4 to another key using xmodmap or other tools.
< -- However, you can use another modifier like Mod1, but it may interact with others.
---
> -- modkey
54a54,57
> 
> 
> 
> 
58,69c61,73
<     awful.layout.suit.floating,
<     awful.layout.suit.tile,
<     awful.layout.suit.tile.left,
<     awful.layout.suit.tile.bottom,
<     awful.layout.suit.tile.top,
<     awful.layout.suit.fair,
<     awful.layout.suit.fair.horizontal,
<     awful.layout.suit.spiral,
<     awful.layout.suit.spiral.dwindle,
<     awful.layout.suit.max,
<     awful.layout.suit.max.fullscreen,
<     awful.layout.suit.magnifier
---
>     -- delete useless layouts
>     awful.layout.suit.tile,               -- 1 (tile.right)
>     awful.layout.suit.tile.left,          -- 2
>     awful.layout.suit.tile.bottom,        -- 3
>     -- awful.layout.suit.tile.top,           -- 
>     -- awful.layout.suit.fair,               -- 
>     -- awful.layout.suit.fair.horizontal,    -- 
>     -- awful.layout.suit.spiral,             -- 
>     -- awful.layout.suit.spiral.dwindle,     -- 
>     awful.layout.suit.max,                -- 4
>     -- awful.layout.suit.max.fullscreen,     --
>     -- awful.layout.suit.magnifier,          --
>     awful.layout.suit.floating            -- 5
73a78
> beautiful.wallpaper = "/home/xatierlike/Pictures/goodbye.jpg"
82c87
< -- Define a tag table which hold all screen tags.
---
> -- Each screen has its own tag table.
85,86c90,97
<     -- Each screen has its own tag table.
<     tags[s] = awful.tag({ 1, 2, 3, 4, 5, 6, 7, 8, 9 }, s, layouts[1])
---
>     tags[s] = awful.tag(
>         {"⌨", "☠", "☢", "☣", "☮", "✈", "✍", "♺", "(._.?)"},
>         s,
>         { layouts[2], layouts[2], layouts[2],
>           layouts[2], layouts[2], layouts[2],
>           layouts[5], layouts[5], layouts[2]
>         }
>     )
87a99
> 
112,113c124,142
< -- Create a textclock widget
< mytextclock = awful.widget.textclock()
---
> 
> -- network usage
> netwidget = wibox.widget.textbox()
> vicious.register(netwidget, vicious.widgets.net, '<span color="#CC9090">⇩${eth0 down_kb}</span> <span color="#7F9F7F">⇧${eth0 up_kb}</span>', 3)
> 
> -- clock
> mytextclock = awful.widget.textclock(" %a %b %d %H:%M:%S ", 1)
> 
> -- CPU usage
> cpuwidget = wibox.widget.textbox()
> vicious.register(cpuwidget, vicious.widgets.cpu, '<span color="#CC0000">$1% </span>[$2:$3:$4:$5]' , 2)
> 
> -- memory usage
> memwidget = wibox.widget.textbox()
> vicious.register(memwidget, vicious.widgets.mem, '$2MB/$3MB (<span color="#00EE00">$1%</span>)', 5)
> 
> -- widget separator
> separator = wibox.widget.textbox()
> separator.text  = " | "
190a220,221
> 
>     -- only display systray on screen 1
191a223,230
> 
>     -- add my widgets
>     right_layout:add(netwidget)
>     right_layout:add(separator)
>     right_layout:add(cpuwidget)
>     right_layout:add(separator)
>     right_layout:add(memwidget)
>     right_layout:add(separator)
232,233c271,274
<     awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx(  1)    end),
<     awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx( -1)    end),
---
>     -- these two lines are useless for me XD
>     -- awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx(  1)    end),
>     -- awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx( -1)    end),
> 
245a287
>     -- spawn a new terminal
249a292
>     -- resize the client (on the focus)
252,255c295,302
<     awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1)      end),
<     awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1)      end),
<     awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1)         end),
<     awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1)         end),
---
> 
>     -- what the fuck?
>     -- awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1)      end),
>     -- awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1)      end),
>     -- awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1)         end),
>     -- awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1)         end),
> 
>     -- change window layouts
258a306,318
>     -- i can move and click my mouse with hotkeys!!
>     awful.key({ modkey, "Shift"   }, "h", function () local mc = mouse.coords()
>                 mouse.coords({x = mc.x-15, y = mc.y}) end),
>     awful.key({ modkey, "Shift"   }, "j", function () local mc = mouse.coords()
>                 mouse.coords({x = mc.x, y = mc.y+15}) end),
>     awful.key({ modkey, "Shift"   }, "k", function () local mc = mouse.coords()
>                 mouse.coords({x = mc.x, y = mc.y-15}) end),
>     awful.key({ modkey, "Shift"   }, "l", function () local mc = mouse.coords()
>                 mouse.coords({x = mc.x+15, y = mc.y}) end),
>     awful.key({ modkey, "Shift"   }, "u", function () awful.util.spawn("xdotool click 1") end),
>     awful.key({ modkey, "Shift"   }, "i", function () awful.util.spawn("xdotool click 3") end),
> 
>     -- restore the minimized client
263a324
>     -- run a piece of lua code
270a332
> 
272c334,341
<     awful.key({ modkey }, "p", function() menubar.show() end)
---
>     awful.key({ modkey }, "p", function() menubar.show() end),
> 
>     -- lock my screen
>     awful.key({ modkey }, "F12", function () awful.util.spawn("xscreensaver-command -lock") end),
> 
>     -- shutter as printscreen tools    http://shutter-project.org/
>     awful.key({ }, "Print", function () awful.util.spawn("/opt/shutter/bin/shutter") end)
> 
358,360d426
<     -- Set Firefox to always map on tags number 2 of screen 1.
<     -- { rule = { class = "Firefox" },
<     --   properties = { tag = tags[1][2] } },
428a495,496
> 
> -- vim:set fdm=marker:



Tuesday, January 1, 2013

bye, 2012



年底反省文


首先當然要感謝我的父母以及姊姊,是你們給我一個如此溫暖的家庭

讓我能一個人在新竹時有依靠,有一個能寄託思念的地方





今年談了一場轟轟烈烈(?)的戀愛,雖然結局不太如意

但也還是創造出很美妙的回憶,難過的的就不去想了吧!

謝謝妳河馬,是你陪我度過這段很棒的時光

希望你也能找到比我更適合你的另一半







感謝 NBL 的各位

老闆 Nik 和阿毓經理、正妹會計 Julia 姊姊,還有已經離職的 Memphis

是你們給我如此美好的一份工作,讓我能在新竹悲劇的高物價下養活自己

薪水水平很棒,工作內容又不會太繁重,真的非常喜歡這份工作

雖然工作難免有出差錯,你們對於我這樣一個打雜的工讀生來說

已經是很棒很棒的待遇了,希望來年能繼續在這邊努力









感謝系計中的各位前輩

今年最瘋狂的決定大概是把 SA / NA 課程修完後直接去衝系計中 TA 吧!

身為最年輕的 TA ,在系計中工作備感壓力,同時也覺得自己不足、所欠缺的太多

感謝各位前輩的容忍與指導

讓我在系上這麼棒的環境學習

特別感謝熊熊學長、凱吉學長、博明學長三位 PhD ㄉㄉ

對於一個如此初生之犢般的學弟,盡力指導、幫助我成長學習

此間受用非兩三句話能表達我內心的感激的

以後也請各位前輩多多關照了!










另外要特別感謝 jserv 學長、前輩、以及老闆

是你在今年對我的用心讓我重新對於資訊工程這條道路感到無比的希望

是你帶我認識各式各樣有趣的開源專案,也介紹了很多很棒的技術

感謝你在暑假時給我的  intern 機會,讓我買了這台我覺得不是很好用的 MBA (炸

每次跟學長談天聊聊自己的處境時,總是會帶給我動力

讓我在這條孤單的道路下能夠繼續前進












感謝 ijsung 學長

是你在今年啟發了我對於 compiler 領域的興趣

無論是在學術方面還是生涯規劃都帶給了我明確的方向

無論是噗浪上閒聊還是對於資訊領域的認真探討

各種方面學長都帶給了我許多

希望能有機會成為跟學長一樣強悍的ㄉㄉ









感謝噗浪上開源社群的夥伴以及各位 hacker

是你們讓我開了眼界

對於資訊安全這條孤寂的道路中給我指引明燈

無論是噗上還是聚會上的嘴砲,一起對於技術的探討以及開源專案的熱情

是你們帶給我一起學習的勇氣!

特別是今年 HIT 的四位隊友和其他共同 hacking 的夥伴

BlueT, 魏藥, TW1943 ,跟你們一起拿下今年駭客年會的亞軍真的很棒

也謝謝其他台灣資訊安全以及開源軟體社群各位的付出和努力!

希望自己以後能繼續能對於整個自由軟體和安全有所貢獻

happy hacking!











要感謝 NBA 社團的各位和交大資工的同學好友們

跟你們一起在這們悲劇的環境下學習真的很棒

雖然還是找不到真正能討論的同窗

不過有你們就不錯惹(







感謝 NC7U-WTF channel 的各位

一起  24 Hr 歡樂聊天、作業討論、婊人、髒髒物分享(?)

科科









最後要感謝小趴、芝芝、君君、鈉鎳、秀你們幾個學妹

有你們這些學妹陪著一位可憐的阿宅

只能用 QAQ (yay) 來形容我的心情惹

我只是想要找個人討拍 QQQQ





來年加油!



xatier 20130101