如论如何,还是不习惯 Ubuntu 的 Unity 桌面,捉摸着怎么将此桌面换成之前熟悉的 Gnome 呢,搜了一大圈互联网,终于在这篇文章里面找到了方法,试了试,还不错,只是没有删除 Unity 的方法,不过这个并不重要,删不删都无所谓。

稍微翻一下,以后用得着,别人也可以用。

1. 先安装 Gnome Packages。

打开终端,输入

sudo apt-get install ubuntu-gnome-desktop ubuntu-gnome-default-settings

此时如果出现选择 GDM 或者是 LightGDM 的话,请选择 GDM。

如果,你已经使用了 GDM 或者系统没有出现选择设置的界面,或者你选择了使用 LightGDM 的话,那么你可以使用下面的命令来重新设置。

sudo dpkg-reconfigure gdm

当然,不是非要一定使用 GDM 的,也可以使用 LightGDM 但是这样就不能体验完整的 Gnome 3 了。

同时,最好可以将 ubuntu-setting 这个包给删除掉(我没有删除,用的没有问题)。至于这个包是干嘛的,这里就不翻译了,反正说的是删不删对使用都没有影响。不过删除了之后,某些 ubuntu 默认的设置就会被改变,例如窗口的按钮顺序, Rhythmbox 插件也是靠这个包来启用的。

这样就完了,接下来的是可选的步骤。

2. 安装一些其它的 Ubuntu 的包,例如 GNOME Documents 和 Boxes(做了这一步,但是基本没用,我也不知道干嘛的)。

sudo apt-get install gnome-documents gnome-boxes

注:因为一个 bug boxes 只在 64位上才可用,32位这里就不要装了。

3. 更新 GNOME Control Center, Nautilus, Totem 以及其他的 GNOME 3 packages 到 3.6.x(这一步也没有做)

不过要先加一个 PPA 才行。

sudo add-apt-repository ppa:gnome3-team/gnome3

然后请遵循这个文章,或者用系统更新来安装。

如果安装了 PPA 之后,有些包将会被更新为: GNOME Control Center 3.6.3, Aisleriot 3.6.0, Brasero 3.6.0, Nautilus 3.6.3 以及 Totem 3.6.2.这个 PPA 同样提供了 Transmission 0.7.1, Transmageddon 0.23 以及 Sound Juicer 3.5.0(至于这些软件都是干嘛的,我也不知道,我没有用,没有做到这一步,也就没有更新)。

4. 删除 overlay scrollbars(这一步也没有做)
到这一步,基本就完成了,但是这里使用的还不是 Gnome 的 overlay scrollbars 而是 Ubuntu 自己的,所以通过下面的命令,将 Ubuntu 自己的 overlay scrollbars 删掉,从而使用 Gnome 3 的。

5. 然后就是重启了,当然注销也可以,只是注销看不到登陆界面的效果。

回调与作用域

在前面的例子中,执行回调的函数一般都如下所示:

    a(b);

而回调一般都如下所示:

    b(parameters);

这在一般情况下都可以正常的工作,但在某些时候,回调并不仅仅是单一的函数,而是某个对象的方法,并且如果该回调使用 this 来引用其所属的对象的话,就会导致错误发生。

假如有一个 add 的回调函数,它是 app 对象的一个方法:

	var app = {};  
	app.number = 1;  
	app.add = function (n) {  
		n = n + this.number;  
	};

makeArray 函数做了类似下面的事:

var makeArray = function (callback) {  
	// ...  
	if (typeof callback === "function") {  
		callback(i);  
	}  
	// ...  
};

调用

makeArray(app.add);

当调用的时候,它并不能按照预期的那样工作,因为 this.number 将会是 undefined。这里 this 将会指向全局对象,因为 makeArray 是一个全局函数。

如果 makeArray 是某个对象的方法,那么在回调函数中的 this 将会指向这个对象而不是期望的 app。(详情请了解下 javascript 中的 this)

解决这个问题的方法就是传递一个回调函数,此外再传递这个回调函数属于的对象作为一个参数:

makeArray(app.add, app);

紧跟着,我们需要去修改 makeArray 去绑定(bind)传递进来的对象:

var makeArray = function (callback, callback_obj) {  
	//...  
	if (typeof callback === "function") {  
		callback.call(callback_obj, i);  
	}  
	// ...  
};

对于传递一个对象和一个被用来回调的方法,另一个可选的方法就是将方法作为字符串传递,那么你就不会重复对象两次。换言之:

makeArray(app.add, app);

会变成:

makeArray("add", app);

那么 makeArray 将会变为如下面几行所示:

var makeArray = function (callback, callback_obj) {  
	if (typeof callback === "string") {  
		callback = callback_obj[callback];  
	}  
	//...  
	if (typeof callback === "function") {  
		callback.call(callback_obj, i);  
	}  
	// ...  
};

匿名的事件监听器

回调模式在日常中被经常使用,比如,当你附加一个事件监听器给页面上的某个元素时,你实际上提供了一个指向了回调函数的引用,并且在事件发生时被调用。

这里有个例子,怎么将 console.log() 作为一个回调函数监听文档的 click 事件:

	document.addEventListener("click", console.log, false);

绝大部分客户端浏览器都是事件驱动的(event-driven),当一个页面加载完成,会触发load事件,然后用户可以通过和页面交互触发各种各样的事件,比如:click, keypress, mouseover, mousemove等等,因为回调模式,JavaScript特别适合事件驱动编程,能让你的程序异步的工作,换言之,就是不受顺序限制。

在异步的事件驱动的JavaScript,可以提供一个回调函数用于在正确的时候被调用;有时候甚至可能提供比实际请求还要多的回调函数,因为某些事件可能不会发生,比如:如果用户不点击“购买”按钮,那么你用于验证表单格式的函数永远不会被调用。

定时

另一个使用回调模式的例子就是使用浏览器的window对象的setTimeout()和setInterval()方法,这些方法也可以接受和执行回调函数:

	var thePlotThickens = function () {  
		console.log('500ms later...');  
	};  
	setTimeout(thePlotThickens, 500);

再次注意一下,thePlotThickens 是如何被作为一个参数传递的,注意这里仍旧没有使用括号,因为你不想它立即执行,传递字符串 “thePlotThickens()” 取代函数的引用和eval()类似,是不好的模式。

当然可以提供匿名函数的方式进行调用。

	setTimeout(function(){thePlotThickens()}, 500);

回调

在 javascript 中,函数都是对象,这也就表明了他们也可以被作为参数,从而传递给其他函数。例如,将函数 a() 作为参数传递给 b() 时,那么,在某一时刻 b() 可能会执行或者说调用 a(); 在这种情况下,a() 就被称作毁掉函数(callback function),也可简称为回调(callback)。

代码示例:

    function b(callback) {
        // do something
        callback();
    }

    function a() {
        // do something
    }

    b(a);

这里需要注意的是,在 b(a) 中,作为参数的 a 函数,是不带括号的,括号表示要执行(此函数),而此处只需要将 a 函数传递给 b 函数,让 b 函数在适当的时候,加上括号调用它即可。

注:可以使用 火狐,或者谷歌的 javascript 控制台,如果调用 console.log(a) 的话,就会得到 a 的函数的定义代码,而前面说了括号表示要执行,所以加上括号之后,表示要执行 a 函数的代码,a 其实只是一个名字而已。

代码改写示例

首先不使用回调的方式来定义两个函数,然后使用回调的方式重构这两个函数。

使函数具有通用的,单一功能的行为,这是非常好的思想,可以对函数的功能一目了然,阅读和修改也更方便。下面两个函数都是用这种思想来定义。

makeArray 函数用来生成一个大数组,并且返回这个大数组。

    var makeArray = function () {
        var i     = 100000,
            array = [];
        while (i) {
            i --;
            array.push(i);
        } 
        return array;
    }

arrayPlus 函数的功能只对数组的元素进行处理。

    var arrayPlus = function (array) {
        var i   = 0,
            max = array.length;
        for(; i < max; i++) {
            console.log(array[i] + 1);
        }
    }

执行这两个函数

    arrayPlus(makeArray());  // 生成数组,并给所有的数字元素 +1 再返回此数组

函数达到了我们的目的,但是对于客户端 javascript 来说,性能在一定程度上也是至关重要的,但是上面的实现是比较低效率的,因为生成数组的 makeArray 有一遍大循环,而处理数组元素的 arrayPlus 函数,做了同样的一遍大循环。如果将 makeArray 中的 array.push(i); 改为 array.push(i+1); 即可,这样是高效的,但是这样生成数组和处理数组高度耦合,其并不再是一个通用的具有单一功能的函数,不符合我们的思想。

那么我们尝试使用回调的方式来重构

    var makeArray = function (callback) {
        var i     = 100000,
            array = [];
        while (i) {
            i --;
            if(typeof callback === 'function'){
                callback(i);
            }
            array.push(i);
        } 
        return array;
    }

    var arrayPlus = function (n) {
        console.log(++n);
    }

重构之后的代码,makeArray 唯一额外的任务是要检查是否有提供回调函数,如果有则执行,如果没有则不执行,并没有破坏原来 makeArray 函数的功能,makeArray 仍然可以像以前一样使用。而 arrayPlus 则变得更加简单。

调用,执行即可

    makeArray(arrayPlus);  // 注意和重构前的调用对比

对于回调函数来说,可以是已经定义好的函数,也可以是匿名函数,在调用主函数时创建回调函数,例如:

    makeArray(function(n){
       console.log(++n); 
    });

主题名称: wSpring 系列 Insects Awaken / 惊蛰
主题链接: https://yimity.com/2013/03/15/wordpress-free-theme-insects-awaken.html
主题描述: Insects Awaken. 单栏主题,支持后台选项,包括自定义站点统计,页面上部背景自主更换,是否显示头像以及阅读模式和浏览模式的切换,SEO 友好,支持自定义菜单,支持IE8以上,及 Chrome,Firefox,Opera等现代浏览器。不需要任何插件支持。
主题版本: 1.0
主题作者: 一米
发布日期:03月15日。
主题预览:https://yimity.com/
灵感来源:http://www.diandian.com/themes/110/show 咖啡因折页,感谢。
介绍:
Insects Awaken. 单栏主题,支持后台选项,包括自定义站点统计,页面上部背景自主更换,是否显示头像以及阅读模式和浏览模式的切换,SEO 友好,支持自定义菜单,支持IE8以上,及 Chrome,Firefox,Opera等现代浏览器。不需要任何插件支持。即使 JS 加载失败,功能同样正常可用。文章样式已经定义好,几乎所有的文章发表即可正常显示。支持 10 种文章格式。只支持多说评论系统。请使用多说的 WordPress 插件,后台有说明。全站 placeholder 支持。极度个性化的 404 页面。

更多…

接上一篇

1. 进入 SVN 的 hooks 目录

cd /home/svn/node/hooks

2. 新建post-commit文件

3. 输入以下内容

#!/bin/sh
REPOS=$1
REV=$2
time=`date "+%Y-%m-%d %H:%M:%S"`
export LANG=C.UTF-8

# 当用户提交的时候注释里包含 auto_deploy 字符串的时候才发布到 web 目录
if (/usr/local/svn/bin/svnlook log -r $REV /home/svn/node/ | grep "auto_deploy")
then
echo "start deploy $time" >> /tmp/svn_autocommit.log
/usr/local/svn/bin/svn export --username yimity --password ******* "svn://127.0.0.1" /home/wwwroot/ajax --force --no-auth-cache
fi

为了不使每次提交之后都发布,所以判断下 只有在提交的注释中包含 auto_deploy 时,才发布。
注意其中的 /usr/local/svn/bin/ 和 /home/svn/node/ 以及 /home/wwwroot/ajax 这三个路径,第一个是安装 svn 的路径,上一篇有讲,第二个是 svn 的版本库目录,第三个是网站服务器目录,至于 svn://127.0.0.1 这个则是 svn 的访问目录了,也可以是外部地址,即:工作电脑获取的地址。
注意 export LANG=C.UTF-8 请看问题 2 字符集。

4. 修改权限

chmod +x post-commit

保存,在本地修改保存提交试试看。

出现错误:
1. Store password unencrypted
进入

vi /home/root/.subversion/servers

将所有的

# store-plaintext-passwords = no

改成

# store-plaintext-passwords = yes

即可

2. 字符集
使用

locale -a

查看系统字符集,如我的 VPS 只有

C
C.UTF-8
POSIX

所以设置成 zh_CN.UTF-8 就会出错

然后设置 3 中的

export LANG=C.UTF-8

修改为

export LANG=系统列出来的字符集的名字

3. 权限
如果新建了不同的组和用户(非 root),权限问题的话,肯定应该会有,比较复杂,这里不多说了。

参考:http://blog.51yip.com/server/901.html 以及 http://www.wp1998.net/2012/834.html

此处所说的独立,是指不结合 apache,也就是你的 ubuntu 可以不安装 apache ,然后独立安装这个 Subversion。

虽然说某些事情有前奏非常好,但是咱们这里就不要前奏了,直接进入主题吧。

1. 下载必要的软件
这里以临时目录为基础。
进入临时目录

cd /tmp

然后下载需要的软件

wget http://subversion.tigris.org/downloads/subversion-1.6.1.tar.gz
wget http://subversion.tigris.org/downloads/subversion-deps-1.6.1.tar.gz

(上面二个压缩文件解压后会放到同一个文件下,不要另建文件夹,这一句可忽略)

2. 安装
解压

tar zxvf subversion-1.6.1.tar.gz
tar zxvf subversion-deps-1.6.1.tar.gz

进入目录,编译安装,视服务器性能需要比较长的时间,可以使用 screen 命令

cd subversion-1.6.1/
./configure --prefix=/usr/local/svn
make && make install

此处将 svn 安装到了 /usr/local/svn 目录。

3. 查看 svn 信息

# /usr/local/svn/bin/svnserve --version
svnserve, version 1.6.1 (r37116)
compiled Jul  7 2010, 23:06:21

如果出现类似 version 1.6.1 的信息,说明安装成功了。

4. 将 svn 的 bin 目录加到环境变量中去

# PATH=$PATH:/usr/local/svn/bin
# export PATH

通过键入 svn 查看是否成功

# svn
Type 'svn help' for usage.

出现这样的字样,就说明成功了

5. 建立仓库
5.1 建个 svn 的根目录,因为项目不只一个,默认放到 home 目录中

# mkdir -p /home/svn    #-p 的意思是说如果没有父目录建之

5.2 建个仓库

# mkdir -p /home/svn/node
# svnadmin create /home/svn/node 或者 # svnadmin create /home/svn 记不清楚了

5.3 导入数据

# svn import ./svntest file:///home/svn/node -m "Initial repository test"
Adding         svntest/test.php
Committed revision 1.

./svntest 为要导入的目录,里面还有相应的项目文件此处使用 test.php 测试。如果出现如上例代码中的字样,则表示导入数据成功

6. 配置
6.1 修改 svnserve.conf(/home/svn/node/conf)

# vi svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = passwd

6.2 修改用户密码文件 passwd

# vi passwd
[users]
yimity = ******(密码)

vi 的使用这里就不说了,i 进入编辑模式,修改完成后按 esc 进入一般模式,然后 :wq 保存退出。

7. 启动

# svnserve -d -r /home/svn/node

然后在本地安装 svn 客户端,获取就可以了。

参考:linux svn安装和配置,不结合apache