Category: Linux

Archlinux更新时gcc-libs-multilib冲突问题解决方法

用64位Archlinux的童鞋大多都会装上gcc-libs-multilib吧,不然没法儿装上wine。不过最近在更新的时候发现了一个纠结的依赖关系问题。在执行pacman -Syu的时候会提示需要先更新pacman,如果选择先安装pacman的话则会告诉你需要安装gcc-libs, 而gcc-libs和已经安装的gcc-libs-multilib冲突。

按理说因为gcc-libs-multilib已经provide了gcc-libs这个包,在判断依赖关系的时候应该是被看作和gcc-libs等价的,但是为什么还会出这种问题捏?搜索了以下发现是pacman的一个bug。而解决的办法就是先手动把pacman更新,然后在执行整个系统的更新:

1
2
sudo pacman -S pacman
sudo pacman -Su

目前为止(12年4月中旬)这个bug仍然存在,需要用上述方法绕开这个问题。

Enhanced by Zemanta

Linux下Nvidia显卡双屏设置

这两天给实验室的电脑加了一个显示器,发现装好gnome的archlinux不能自动识别,因此折腾了一下双显示器的配置问题。对于双屏幕的设置有Xinerama, Twinview, randr等方法。

Xinerama

对于Archlinux下的Xorg的双屏设置,默认情况下只会使用第一个显示器。如果想要使用双屏,最直接的办法是使用Xorg的Xinerama扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Section "ServerLayout"
    Identifier     "DualSreen"
    Screen       0 "Screen0"
    Screen       1 "Screen1" RightOf "Screen0" #Screen1 at the right of Screen0
    Option         Xinerama "1" #To move windows between screens
EndSection
 
Section "Monitor"
    Identifier     "Monitor0"
    Option         "Enable" "true"
EndSection
 
Section "Monitor"
    Identifier     "Monitor1"
    Option         "Enable" "true"
EndSection
 
Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    Screen         0
EndSection
 
Section "Device"
    Identifier     "Device1"
    Driver         "nvidia"
    Screen         1
EndSection
 
Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    Option         "TwinView" "0"
    SubSection "Display"
        Depth          24
        Modes          "1280x800_75.00"
    EndSubSection
EndSection
 
Section "Screen"
    Identifier     "Screen1"
    Device         "Device1"
    Monitor        "Monitor1"
    DefaultDepth   24
    Option         "TwinView" "0"
    SubSection "Display"
        Depth          24
    EndSubSection
EndSection

只需要把上述内容保存在/etc/X11/xorg.rc.d/10-monitor.conf就可以开启双屏输出了。但是不知道为什么我使用这个方法配置的时候两个屏幕的内容会出现重叠,屏幕分辨率也有问题,尝试了各种配置都没有完全解决。使用Xinerama扩展来双屏输出还有一个问题就是不能支持composition。

Twinview

因此我转向使用nvidia提供的另外一个方法:使用nvdia显卡驱动的twinview扩展,最简单的方法就是运行

1
sudo nvidia-xconfig --twinview

这会生成一个/etc/X11/xorg.conf,并且会忽略/etx/X11/xorg.rc.d/10-monitor.conf中的设置。使用twinview方式显卡驱动会将两个显示器拼成一个显示器–这意味着你在gnome, kde的显示器设置中只会看到一个显示器,它的分辨率是两个显示器之和。因此在xorg.conf中也只需要配置一个显示器,具体配置文件的用法可以参考这里,你可以在配置文件里面手动指定两个屏幕的分辨率等等。用这个方法的好处是可以有桌面特效加速,但是用ATI显卡的同学就不能这么用了。

自动生成的配置有一个问题:显卡的第二个接口连接的显示器分辨率最多只能上到640X400,解决的方法也很简单,只需要把Monitor中的HorizSync和VertRefresh注释掉就可以了:

1
2
3
4
5
6
7
8
9
Section "Monitor"
        Identifier      "Monitor0"
        Option          "Enable"   "True"
        VendorName      "Unknown"
        ModelName       "Unknown"
        #HorizSync      28.0 - 33.0
        #VertRefresh    43.0 - 72.0
        Option          "DPMS"
EndSection

如果你已经可以启动图形界面的话,可以用管理员权限运行nvidia-settings来用nvidia驱动自带的GUI程序对双屏幕进行设置,设置会自动保存到xorg.conf中。

针对Wine的设置

如果使用Twinview方式设置双屏的话,wine下运行的程序会不正常–在我的机器上如果是两个分辨率不一样的屏幕左右排列,右边个屏幕上的wine程序就会有一块是白板。如果是运行游戏的话鼠标会被限制在一个小范围中,不能点到整个屏幕。

解决这个问题的折衷办法是在twinview的分辨率模式中为wine下面的游戏添加一个模式–让主显示器用正常分辨率,把另外一个显示器关掉:

1
2
3
4
5
6
7
8
9
10
11
12
13
Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    Option         "TwinView" "1"
    Option         "TwinViewXineramaInfoOrder" "CRT-1"
    # 第一个模式是自动匹配最佳分辨率,第二个是在运行游戏的时候关掉一个显示器
    Option         "metamodes" "nvidia-auto-select,nvidia-auto-select;NULL,1440x900"
    SubSection     "Display"
        Depth       24
    EndSubSection
EndSection

OpenVPN配置

最近一直用的OpenVPN服务到期了,然后自己在VPS上面搭建了一个OpenVPN服务,发现速度还不错。看Youtube HD毫无压力。将配置记录如下。

首先需要的是制作证书。服务器端必须生成证书和密钥,而客户端可以选择使用证书或者是密码验证的方式。这里给出的配置是使用证书验证的方法。

生成证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 这里使用easy-rsa工具来生成证书
$cp /usr/share/openvpn/easy-rsa/ ~/easy-rsa
$cd $_
 
#修改vars文件中的下面那几个变量,这些都会显示到证书里面的,建议还是修改下
# export KEY_COUNTRY="CN"
# export KEY_PROVINCE=""
# export KEY_CITY=""
# export KEY_ORG=""
# export KEY_EMAIL=""
$ vim vars
 
#初始化变量
$ source ./vars
 
#初始化
$ ./clean-all
 
#制作CA证书
#最后会在keys目录下生成 ca.crt(根证书文件) 和 ca.key(根证书私钥文件)
$ ./build-ca
 
#制作服务器端证书
#最后会在keys目录下生成 server.crt(证书文件) 和 server.key(私钥文件)、server.csr(证书请求文件)
$ ./build-key-server server
 
#制作客户端证书
#最后会生成客户端使用的证书
$ ./build-key client1
 
#如果某个客户端证书不需要用了,可以注销客户端证书
$ ./revoke-full client1
 
#创建Diffie Hellman参数
$ ./build-dh

然后将服务器的证书拷贝到/etc/openvpn下面,客户端证书拷贝到客户端配置文件同一个目录下。

OpenVPN配置

服务器端配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 服务器的端口
port 1194
 
# 使用udp还是tcp协议,选啥都一样
proto tcp
;proto udp
 
# tap和tun二选一,没有特殊需求不用变
;dev tap
dev tun
 
# 指定证书、密钥
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
 
# 服务器在vpn连接中的地址
server 10.8.0.0 255.255.255.0
 
ifconfig-pool-persist ipp.txt
 
# 转发客户端的数据
push "redirect-gateway def1 bypass-dhcp"
# 告诉客户端换成8.8.8.8的dns服务器
push "dhcp-option DNS 8.8.8.8" 
 
# 是否允许同一个证书的多个客户端登陆,注释掉的话后登陆的客户端会把前面一个挤掉
duplicate-cn
 
keepalive 10 120
 
# 使用数据压缩
comp-lzo
 
persist-key
persist-tun
status openvpn-status.log
verb 3

将该配置文件保存为/etc/openvpn/server.conf,然后再重启openvpn服务就可以了:

1
 sudo /etc/init.d/openvpn restart

 

客户端配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
client
 
;dev tap
dev tun
 
proto tcp
;proto udp
 
# 指定服务器地址
remote server.com 1194
 
resolv-retry infinite
 
nobind
 
persist-key
persist-tun
 
;mute-replay-warnings
 
# 指定客户端使用的证书和密钥
ca ca.crt
cert client1.crt
key client1.key
 
ns-cert-type server
 
comp-lzo
 
verb 3
 
;mute 20
 
redirect-gateway
route-method exe
route-delay 2
route-up "net stop dnscache"
route-up "net start dnscache"
route-up "ipconfig /flushdns"
route-up "ipconfig /registerdns"

配置数据转发

为了能够让服务器真正将数据转发出去,还需要一点点防火墙的配置:

1
2
3
# iptables -t nat -A POSTROUTING -s $LOCAL_NETWORK -o eth0 -j MASQUERADE
# cat 1 > /proc/sys/net/ipv4/ip_forward
# iptables -A INPUT -i tun0 -j ACCEPT

iptable的设置在重启以后会丢失,可以用如下命令将它们保存下来:

1
# rc.d save iptables

同时可以编辑/etc/sysctl.conf中的设置:

1
net.ipv4.ip_forward=1

这样重启以后只需要直接启动openvpn的daemon就可以了

nginx配置备忘

安装

在ubuntu 10.10里面还没有专门的fastcgi包,必须通过lighttp里面附带的fastcgi加上自定义的脚本来启动fastcgi进程。但是在ubuntu 11.10里面有了一个php5-fpm的包专门用来处理fastcgi,免去了自己倒腾脚本的麻烦。把这一堆包装上安装就算是完事了:

1
sudo apt-get install nginx php5 php5-fpm mysql-server mysql-client

配置

配置也很简单,直接在/etc/nginx/sites-avalable里面添加一个自己的配置文件,然后创建一个到/etc/nginx/sites-enabled/的软链接即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server {
        listen   80; ## listen for ipv4; this line is default and implied
        root /path/to/root/;
        index index.php index.html index.htm;
 
        # Make site accessible from http://localhost/
        server_name _;
 
        location / {
                # 找不到页面的时候返回到index.html
                try_files $uri $uri/ /index.html;
        }
 
        # 将错误页面重定向到制定的文件
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
                root /usr/share/nginx/www;
        }
 
        # 处理php文件
        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                include fastcgi_params;
 
                # 在使用wordpress必须要有这个rewrite,否则访问rss的时候会出现404错误
                if( !-e $request_filename)
                {
                        rewrite ^/wordpress/(.+)$ /wordpress/index.php?q=$1 last;
                }                        
        }

对Archlinux的怨念

之前之所以开始使用Archlinux是因为觉得ubuntu的软件包更新太慢,有的软件居然用的还是一年多以前的版本。冲着Archlinux的Rolling Release的名号在自己电脑上把它装上了。

事实上Archlinux的确是一个很有特色的发行版,主要在于它的软件包管理系统可以支持用户向软件仓库中提交软件包的编译脚本。通过这个编译脚本它可以自动化的完成下载源代码、编译、打包、安装的过程。因为编译出来的代码是经过打包以后再安装的,自然这就比传统的make install要保险的多,至少你不用担心卸载的问题,同时还能够随时用到最新的软件。

另一个特点是它的包管理器不会去修改你的配置文件,很多升级相关的操作也没有实现自动化(比如说内核升级以后有些内核的mod就必须自己手动编译、设置),而ubuntu则会在内核升级的时候把所有相关的东西都给你设置好。Archlinux的开发者声称这是一个feature而不是一个bug,因为Archlinux的哲学是不会让软件自作聪明。

好吧,看起来这真是一个能让你变成资深黑客的发行版(或者至少是看起来像黑客)。但是用了一段时间以后发现Archlinux有的时候实在是会有让你砸电脑的冲动。它的软件仓库实在是太不靠谱了!我在虚拟机里面跑了几个月的Archlinux,经历了两次更新以后莫名其妙的问题。在直接装到硬盘上以后又经历了两次。或者是更新以后死活进不了gnome,一登录就重新回到gdm;或者是更新完以后直接所有bash命令都失效;或者是告诉你内核出了虾米虾米问题。

当然hacker就要有hacker的样子,找到bug,告诉developer,甚至自己写个补丁发过去。但问题是这种问题通常都是快速出现并且快速消失的。也许这个问题只是在某种特殊情况下出现,当过两天软件更新到某个更新的版本的时候这个问题又不复存在了,每次我都会在irc, news letter, forum, google里面到处问但是却根本没有人知道是怎么回事,看来我是少有的几个遇到问题的倒霉蛋。更要命的是它出问题的时候正是大作业如滔滔江水绵绵不绝的时候,而我想要写篇latex却要用另外一条电脑满世界找不知道藏在哪个犄角旮旯的解决方案。

好吧,我认输。在忙过那一段时间以后又一次直接把archlinux重装了,并且决定要是下一次还在更新以后出问题我就再也不用这个东西了。后来再跟一个朋友聊天的时候知道他以前也用的archlinux,一问才知道他也遇到了所有bash命令出错的问题,一怒之下又装回了ubuntu。看来倒霉的人不止我一个 Orz
以前有人说Linux是一个危险的东西–它会让你不知不觉的把大量时间耗费在无意义的对系统的配置上面,而正经事儿却一件也没有干。对于其他Linux可能未必是这样,但是,Archlinux的童鞋们,小心了。

配置Emacs下的Python开发环境

特性

在Linux论坛上总有人问Python用什么IDE比较好,然后总会有人回答说Emacs。最近开始学Python,也花了点时间研究怎么配置Emacs,发现没有想象中的那么麻烦。这篇文章大致上来自于Lei Chen博客文章的翻译,完成以后的Emacs具有以下特性:

  • 自动完成同一个文件内的变量、函数
  • 自动完成python库中的名称
  • 代码重构
  • 模板展开功能
  • 在线帮助系统
  • 即时语法检测

其他特性还包括自动缩进,括号匹配,语法高亮,代码折叠等等。其中最有用的莫过于自动完成了,貌似很少有python编辑器可以做到这一点。而即时语法检测让emacs下的python代码书写变得像Eclipse一样,一旦有错误立刻就会高亮标记出来。

如何安装

首先你得在home目录下有一个.emacs配置文件,并且有一个用来放插件的文件夹(比如说~/.emacs.d/)

  1. 下载auto-completion.el到.emacs.d,并且在.emacs中添加如下几行:
    (require ‘auto-complete)
    (global-auto-complete-mode t)
    
  2. 下载yasnippet到.emacs.d并且编辑.emacs:
    (require ‘yasnippet) (yas/initialize) (yas/load-directory “~/.emacs.d/snippets”)
  3. 下载python-mode.el并且放到.emacs.d中。我们会在之后的配置中用到它
  4. 设置Rope, Ropemacs 和 Pymacs

    我们需要使用最新的development版的rope和ropemacs,否则在emacs中不能找到rope-completion函数。通过如下步骤安装:

    sudo apt-get install mercurial
    mkdir /tmp/rope && cd /tmp/rope
    hg clone http://bitbucket.org/agr/rope
    hg clone http://bitbucket.org/agr/ropemacs
    hg clone http://bitbucket.org/agr/ropemode
    sudo easy_install rope
    ln -s ../ropemode/ropemode ropemacs/
    sudo easy_install ropemacs
  5. 安装pyflacks以进行自动语法检查:

    sudo apt-get install pyflakes
  6. 把所有东西放到一块儿
  7. 在你的.emacs.d中创建一个init_python.el,并且加入以下内容:

    (autoload 'python-mode "python-mode" "Python Mode." t)
    (add-to-list 'auto-mode-alist '(".py'" . python-mode))
    (add-to-list 'interpreter-mode-alist '("python" . python-mode))
    (require 'python-mode)
    (add-hook 'python-mode-hook
          (lambda ()
    	(set-variable 'py-indent-offset 4)
    	;(set-variable 'py-smart-indentation nil)
    	(set-variable 'indent-tabs-mode nil)
    	(define-key py-mode-map (kbd "RET") 'newline-and-indent)
    	;(define-key py-mode-map [tab] 'yas/expand)
    	;(setq yas/after-exit-snippet-hook 'indent-according-to-mode)
    	(smart-operator-mode-on)
    	))
    ;; pymacs
    (autoload 'pymacs-apply "pymacs")
    (autoload 'pymacs-call "pymacs")
    (autoload 'pymacs-eval "pymacs" nil t)
    (autoload 'pymacs-exec "pymacs" nil t)
    (autoload 'pymacs-load "pymacs" nil t)
    ;;(eval-after-load "pymacs"
    ;;  '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
    (pymacs-load "ropemacs" "rope-")
    (setq ropemacs-enable-autoimport t)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;; Auto-completion
    ;;;  Integrates:
    ;;;   1) Rope
    ;;;   2) Yasnippet
    ;;;   all with AutoComplete.el
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    (defun prefix-list-elements (list prefix)
      (let (value)
        (nreverse
         (dolist (element list value)
          (setq value (cons (format "%s%s" prefix element) value))))))
    (defvar ac-source-rope
      '((candidates
         . (lambda ()
             (prefix-list-elements (rope-completions) ac-target))))
      "Source for Rope")
    (defun ac-python-find ()
      "Python `ac-find-function'."
      (require 'thingatpt)
      (let ((symbol (car-safe (bounds-of-thing-at-point 'symbol))))
        (if (null symbol)
            (if (string= "." (buffer-substring (- (point) 1) (point)))
                (point)
              nil)
          symbol)))
    (defun ac-python-candidate ()
      "Python `ac-candidates-function'"
      (let (candidates)
        (dolist (source ac-sources)
          (if (symbolp source)
              (setq source (symbol-value source)))
          (let* ((ac-limit (or (cdr-safe (assq 'limit source)) ac-limit))
                 (requires (cdr-safe (assq 'requires source)))
                 cand)
            (if (or (null requires)
                    (>= (length ac-target) requires))
                (setq cand
                      (delq nil
                            (mapcar (lambda (candidate)
                                      (propertize candidate 'source source))
                                    (funcall (cdr (assq 'candidates source)))))))
            (if (and (> ac-limit 1)
                     (> (length cand) ac-limit))
                (setcdr (nthcdr (1- ac-limit) cand) nil))
            (setq candidates (append candidates cand))))
        (delete-dups candidates)))
    (add-hook 'python-mode-hook
              (lambda ()
                     (auto-complete-mode 1)
                     (set (make-local-variable 'ac-sources)
                          (append ac-sources '(ac-source-rope) '(ac-source-yasnippet)))
                     (set (make-local-variable 'ac-find-function) 'ac-python-find)
                     (set (make-local-variable 'ac-candidate-function) 'ac-python-candidate)
                     (set (make-local-variable 'ac-auto-start) nil)))
    ;;Ryan's python specific tab completion
    (defun ryan-python-tab ()
      ; Try the following:
      ; 1) Do a yasnippet expansion
      ; 2) Do a Rope code completion
      ; 3) Do an indent
      (interactive)
      (if (eql (ac-start) 0)
          (indent-for-tab-command)))
    (defadvice ac-start (before advice-turn-on-auto-start activate)
      (set (make-local-variable 'ac-auto-start) t))
    (defadvice ac-cleanup (after advice-turn-off-auto-start activate)
      (set (make-local-variable 'ac-auto-start) nil))
    (define-key py-mode-map "t" 'ryan-python-tab)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;;; End Auto Completion
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Auto Syntax Error Hightlight
    (when (load "flymake" t)
      (defun flymake-pyflakes-init ()
        (let* ((temp-file (flymake-init-create-temp-buffer-copy
    		       'flymake-create-temp-inplace))
    	   (local-file (file-relative-name
    			temp-file
    			(file-name-directory buffer-file-name))))
          (list "pyflakes" (list local-file))))
      (add-to-list 'flymake-allowed-file-name-masks
    	       '(".py'" flymake-pyflakes-init)))
    (add-hook 'find-file-hook 'flymake-find-file-hook)
    (provide 'init_python)
    
  8. 在你的.emacs文件中添加:(load-library “init_python”)

使用说明

  1. 代码自动展开。比如说在编辑C/C++头文件的时候键入once然后按tab,则会自动展开#ifndef __FILE_H__这样的宏。这个功能是YASnippet提供的,在emacs的菜单中可以看到它的所有宏。展开以后再按tab键可以在已展开的代码之间切换位置。
  2. 自动完成代码。函数名输入到一半按tab键会调用Rope和Ropemacs的功能自动完成库文件中的函数、变量名
  3. C-c d 显示python的doc string
  4. C-c C-c 运行当前的文件
  5. C-c ! 打开python shell

事实上init_python.el做的事情是通过使用auto_complete.el中的功能,把YASnippet和Rope的功能结合到了一块儿,实现了类似TexMate的自动完成等功能。其中YASnippet可以自定义模板,很是实用。Rope的功能还在研究中。

被Awesome打败了

刚才把自己的Awesome更新到了从3.1升级到了3.2版。不出意料,Awesome的配置文件要求又改了,我的配置文件又让无法运行了。也没有什么有价值的出错信息,它仅仅告诉我说我的配置文件是Syntax OK。甚至于用默认的配置文件也没法而让它跑起来…

玩Awesome真是一个费经历的差事…没有多少闲工夫的我还是继续用Gnome吧

在Awesome中怀念八位机

按理说一个窗口管理器是不应该和怀旧小游戏扯上多大关系的,但是在Awesome中这的确发生了。前两天在把玩Awesome的时候发现源代码的icon文件夹里面有一写叫做enemy和player的图片,就像这个样子:
enemy_1.pngenemy_2.pngenemy_3.pngplayer.png
这不禁让人纳闷,难道Awesome里面还有彩蛋之类的程序?搜索了一下发现还真有这么一个东西,这就是invader。

invader是一个用lua脚本写的小游戏,整个代码只有一个五百多行的文件。通过如下方法可以运行它:

$awesome-client
require("invaders")
invaders.run()

游戏显示在桌面背景上,所以如果你当前桌面上开的有窗口的话会把它挡住。你会看到一个类似八位机时代小蜜蜂的游戏。似乎是没有多大用处,但是想想看用lua脚本就可以在桌面上绘制这么些东西,那么完全有可能做出利用Awesome提供的lua库做出很多很有意思的东西出来。现在官方网站上能找到的Awesome的lua脚本还比较少,但是浏览了一下它的lua接口,发现已经有模有样了。如果有足够多的用户为它贡献lua插件的话说不定能发展成一个异常强大且快速的窗口管理器。

Make快速上手

前段时间在在开源俱乐部里面讲了一下Make的使用,把幻灯片和相应的源代码上传到这里:
beginning_make.pdf
make_demos.tar.gz

之前网上曾经有一个《跟我一起写Makefile》的pdf,但是个人感觉里面写的结构比较零散,我的这个幻灯片看起来也还是不太方便,等到有空以后重新写一篇blog发上来。

Awesome使用&简单配置

默认键位

如果你是一个和我一样懒的人,不介意自己的手指头被默认键位扭曲得像麻花的话,那么完全可以参照我这里给出的部分默认键位的介绍:)

当然你可以通过修改配置文件来更改这些键位。这里的Mod4可以在配置文件中定义,默认是Windows键。

Mod4 + Return
打开一个终端
Mod4 + F1
运行命令
Mod4 + Shift + c
关掉当前窗口
Mod4 + Control + r
重启awesome
Mod4 + Shift + q
退出awesome

Mod4 + j
切换到下一个窗口
Mod4 + k
切换到前一个窗口
Mod4 + Left
查看前一个tag
Mod4 + Right
查看后一个tag
Mod4 + 1-9
切换到tag 1-9
Mod4 + Control + j
切换到下一个屏幕
Mod4 + Control + k
切换到前一个屏幕

Mod4 + Shift + j
当前窗口和前一个窗口互换位置
Mod4 + Shift + k
当前窗口和后一个窗口互换位置
Mod4 + h
把主区域(master width)的宽度增大5%
Mod4 + l
把主区域(master width)的宽度减少5%
Mod4 + Shift + h
增加主区域窗口的数量
Mod4 + Shift + l
减少主区域窗口的数量
Mod4 + Control + h
增加非主区域窗口的数量
Mod4 + Control + l
减少非主区域窗口的数量
Mod4 + space
把当前tag更换为下一种布局
Mod4 + Shift + space
把当前tag更换为前一种布局
Mod4 + Control + space
切换当前窗口是否为浮动的

Mod4 + Shift + i
显示当前窗口的class和instance。这在写脚本的时候尤其有用

Mod4 + Shift + r
重绘当前窗口

配置

修改xinitrc

你已经按照之前的步骤安装上了Awesome。但是你会发现进去以后几乎什么都没有,gnome程序的界面没有了主题变得极其丑陋,屏保也不会自动运行了。其实只需要一些设置你就能让它变得很顺手。

首先我们来修改.xinitrc中的内容。

#!/usr/bin/env bash
sleep 100
xsetroot -solid black &
#启动屏保程序
gnome-screensaver &
#启用gnome的主题,否则你的awesome下的gnome程序会非常难看
gnome-settings-daemon &
#电源管理程序
gnome-power-manager &
#网络管理程序
nm-applet &
#自动更新程序
update-notifier &
exec /usr/local/bin/awesome

编写rc.lua 让我们来点花样

从3.0开始awesome转而使用lua作为配置文件的格式,配置文件位于~/.config/awesome/rc.lua。这一改变极大的增加了awesome的灵活性,但是也让配置文件变的庞大而复杂。

还好lua不是一门很复杂的语言,所以基本上用不着多少关于lua的专门介绍就可以看明白这个配置文件。你可以运行在awesome下面修改配置文件,然后用快捷键ctr-mod4-R来重新读取配置文件。不过要小心的是如果配置文件里面有错的话有可能整个awesome会直接死掉,这时候就只能重启X了…

注意1:以下的讨论仅适用于awesome3.x版本。8.04源里面的2.4版本用的是完全不同配置文件格式,不能和3.0的通用
注意2:Awesome3的配置文件的格式、lua库函数一直都在变动当中,所以以下说的方法可能只适用于一个特定的git仓库中的版本。等到它稳定以后我会重新更新的:)

因为rc.lua实在是很庞大,没办法每一行都介绍它的意思,所以下面只是介绍一下默认的配置文件中的一些比较有用的部分:

杂项

-- 下面这一行指明了当前配置文件使用的主题文件。awesome的主题非常简单,只需要指明几个颜色就可以了
theme_path = "/usr/local/share/awesome/themes/default"

-- 这里设置默认的终端程序。默认的xterm显示中文有问题,我用的是urxvt
terminal = "urxvt"

-- 还记得之前提到的Mod4键么?你可以在这里重新设置它为其他任意一个键
modkey = "Mod4"

浮动窗口

你下载文件时Firefox打开了一个下载窗口,结果它却可怕的占据了屏幕的一半大小,把其他窗口挤得大小便失禁。英明神武的你当然不想这样。解决方法就是把这样的窗口设置为浮动, 在它们启动的时候就自动把他们设置为浮动窗口,这样就不会让你的屏幕天下大乱了.

-- 需要自动设置为浮动的程序
-- 只需要把你想要设置为浮动窗口的程序的Instance或者class按照下面的格式写进去就行
-- 了。在awesome下用Mod4 + Ctr + i就可以看到当前程序的instance和class名字
floatapps =
{
    ["MPlayer"] = true,
    ["gimp"] = true,
    ["smplayer"] = true,
    ["mocp"] = true,
    ["Codeblocks"] = true,
    ["Dialog"] = true,
    ["Download"] = true,
    ["empathy"] = true,
}

-- 把指定的程序自动移动到某个特定的屏幕的某个tag上面
apptags =
{
    ["smplayer"] = { screen = 1, tag = 7 },
    ["amarokapp"] = { screen = 1, tag = 8 },
    ["VirtualBox"] = { screen = 1, tag = 9 },
    ["Firefox"] = { screen = 1, tag = 1},
    ["Thunderbird-bin"] = { screen = 1, tag = 7 },
    ["Linux-fetion"] = { screen = 1, tag = 6 },
}

我要我的tags

如果你觉得默认的9个tag太多或者是太少,或者是觉得不想用1-9这样的数字来作为Tag 的名字的话,往下看:

-- 下面这个循环创建了默认的9个tag
tags = {}
for s = 1, screen.count() do
    -- 每个屏幕都有一个tag的table(这里所说的table指的是lua中的概念,大致等价于数组)
    tags[s] = {}

    -- 每个屏幕创建9个tag,把9改为其他数字就能改变tag的数目
    for tagnumber = 1, 9 do
        tags[s][tagnumber] = tag({ name = tagnumber, layout = layouts[1] })
        tags[s][tagnumber].screen = s
    end
    -- 另最后一个屏幕的第一个tag处于选中状态
    tags[s][1].selected = true
end

-- 默认的tag名字是数字1-9,对于鼠标点击来说有点太小。
-- 你可以通过如下的方法设置自己的tag名称
tags[1][1].name = "Internet"
tags[1][2].name = "Term"
tags[1][3].name = "IRC"
tags[1][4].name = "Tag1"
tags[1][5].name = "Tag2"
tags[1][6].name = "Tag3"
tags[1][7].name = "Email"
tags[1][8].name = "Music"
tags[1][9].name = "Virtual"

时间

第一次用awesome的人肯定会很奇怪屏幕右上角不断增长的数字是什么?我第一次看到它的时候花了很长时间才反应过来它不是CPI。

-- 显示时间
-- 默认显示的是从1970年1月1日到现在经过了多少秒。话说应该没人喜欢这样的时间显示
-- 难道awesome的作者觉得有人可以心算这个数字得到当前的时间? 囧
-- 查找awful.hooks.timer.register这一行,改为如下的设置就可以显示正常的时间了
awful.hooks.timer.register(1, function ()
    mytextbox.text = " " .. os.date() .. " "
end)

开机自动启动

每次开机都重复打开一些程序并且把它们移动到特定的Tag上面是一件很乏味的事情。Awesome并没有提供一个类似gnome的session管理之类的东西,但是我们可以通过修改配置文件来达到开机自动启动程序的目的。

在rc.lua的任意位置添加如下代码:

-- Autorun programs
autorun = "true"
autorunApps =
{
    "firefox",
    "thunderbird",
    "amarok",
    "linux-fetion",
    "amule",
}

if autorun then
    for app = 1, #autorunApps do
        awful.util.spawn(autorunApps[app])
    end
end

其中把autorunApps中的内容替换为你想要运行的程序就可以了。
注意:X下的程序需要在Awesome启动完毕之后再运行,因而不能放在.xinirc中自动启动。另外在rc.lua中也只能通过 awful.util.spawn(“cmd”)的方式来运行程序,其他的方式比如os.execute或者io.popen都会使awesome失去响应,原因还不清楚。