Linux下关闭多个进程

很多时候,需要同时关闭一系列的有着相同的关键字的进程,比如说,开着十多个网页的chrome死掉了这种情况。。

在Linux下面,敲几个命令就OK了,以下每行都可以,有些区别

ps -e | grep chorme | cut -c 1-5 | xargs kill -9
ps -e | awk '$4=="chrome" {print $1}' | xargs kill -9

ps -e的输出如下

12040 ?        00:00:00 kworker/1:1
12041 ?        00:00:00 kworker/0:0
12052 ?        00:00:09 chrome
12119 ?        00:00:00 kworker/3:0

这个命令输出了当前的所有进程信息,最前面的就是进程的pid。第四列是进程的名称
grep chrome就是查找含有chrome的行并输出。cut -c 1-5意思是对输入的每一行取第1到5个字符(恰好是进程的pid)输出。两个命令合起来,就是输出进程名含有chrome的进程的pid。

awk '$4=="chrome" {print $1}'做了同样的事,不过这个命令输出的是进程名恰好是chrome的进程的pid,而不仅仅是包含。

xargs kill -9这个命令,输入以换行或者空白分割之后,作为参数执行一遍或者多遍后面跟随的命令

最后感叹一下,shell很强大!

安装GitLab

在V2EX上面看了一个如何管理自己的代码的帖子,里面有个回答是使用gitlab,于是搜了一下。。可以这么说,gitlab是开源的github,可以在自己的电脑上搭一个私人的git托管服务,相当不错。对于自己来说,其实就是折腾啦,可以不用把所有的代码都扔到github上面,但是有个不好就是在自己的机器上面,一旦系统挂了,代码就没了。。

安装就是跟着官方的安装文档,一路下来就可以了,由于网络速度以及各种其他问题,我装了两天。需要提醒的一点是,文档里面,安装路径是/home/git/gitlab,建议不要修改,因为有些地方是硬编码了这个路径的,如果修改可能会导致网站不能跑起来。

在安装过程中的需要bundle install的地方,由于众所周知的原因,建议把Gemfile中的地址修改为http://ruby.taobao.org,加快速度。

在安装过程中,我遇到的一些问题:

  • 在Gemfile中有些这样的写法require: :xxx,如果bundle install出现问题,可以把这种写法改成:require => xxx。这个原因是ruby 的版本太老不支持新的语法(但是我的ruby是最新的也报错了。。)
  • 在执行bundle install时,提示需要 ruby的版本大于1.9.2,而实际上我的机器上ruby是1.9.3,这时执行sudo apt-get install gem之后重新执行改命令
  • 安装数据库时,未修改配置文件,导致登录数据库错误。这个只要修改了配置文件即可,注意应该修改production中的配置

安装完成后,有个管理员账户

email:    [email protected]
password: 5iveL!fe

如果要增加用户,只能通过管理员账户新建用户,不能自由注册,毕竟gitlab是私人的托管服务,面向的是小型的团队。

装完之后用了一下,虽然和github很像,功能也比较齐全,和github还是有所不同。建立一个新的项目的时候,不会自动建立新的repo而是需要自己手动建立并push。。当然还有其他区别,在此不一一列举了

自己写sublime text插件

起因是,自己写Python基本上使用sublime text 2。但是,文件头部的代码

#! /usr/bin/env python
# -*- coding: utf-8 -*-

如果每次都要敲的话,很麻烦。而如果不敲的化,一旦涉及中文,又会报错,就产生了写了一个插件的想法。。问题好久了,直到今天才动手,惭愧一下。。

思路应该是比较简单,就是判断文件类型,然后在头部插入特定的字符串。于是乎,开始在网上查找sumblime text 2的API还有插件开发教程。这是API文档中文翻译版,看一下Default里面的自带插件,就可以动手了。

最初的代码中,字符串是硬编码的。后来,则是从模板文件中读取字符串。在这一步,遇到了一个很诡异的问题,是这样的:模板文件保存在templates文件夹下面,在HeadTemplate.py中(我的插件的名字是HeadTemplate),

def get_tpl_file(settings, filename):
    template_root = settings.get('template_root')
    path = os.path.join(os.path.dirname(__file__), template_root)
    return os.path.join(path, filename)

但是这个函数的返回的结果是/home/username/templates/filename,而实际上,我认为应该返回的是/home/username/.config/sublime-text-2/Packages/HeadTemplate/templates/filename。打印os.path.abspath(__file__),得到的结果是/home/username也就是我的家目录。开始以为是由于隐藏文件夹的缘故,不过试验之后,发现与之无关。为什么会有这个结果,具体原因到现在我也还弄不清楚。不过,解决方案倒是找到了,感谢SErHo的代码

PACKAGE_NAME = 'HeadTemplate'
PACKAGES_PATH = sublime.packages_path()

def get_tpl_file(settings, filename):
    template_root = os.path.join(
                    PACKAGES_PATH, 
                    PACKAGE_NAME, 
                    settings.get('template_root'))
    return os.path.join(template_root, filename)

在其他就没有什么了,按部就班的写下来就好了。代码放在了github上,https://github.com/iEverX/HeadTemplate

算上空行不到50,却写了一个下午。。

Javascript遍历DOM树

这个博客是利用Jekyll在github pages上搭建的,显示在首页的文章,如果用{{ post.content | truncate: 200 }},原有的格式不能完全保持,且有时在最后会有乱码。而{{ post.content | truncatewords: 50 }}也有不能保持格式的问题,而且对于中文来说,word的概念大概就变成了句子,截取的长度不能确定。本来truncatehtml这个插件可以解决格式保持的问题,但是出于安全的考虑,github pages不允许运行插件,所以。。。

这个问题有很长时间了,今天闲的没事,用js写了一下。就是遍历DOM树,叠加文本节点的长度,当长度达到既定长度时,其后所有的节点修改style为display: none,用jQuery就是hide(),具体到自己的博客,代码如下,

$(function() {
    function traverse($node, len, maxCount) {
      var reachMaxCount = len > maxCount;
      if (reachMaxCount) {
        $node.hide();
      }
      var $contents = $node.contents();
      for (var i = 0; i < $contents.length; ++i) {
        if (reachMaxCount) {
          $contents.eq(i).hide();
          continue;
        }
        if ($contents[i].nodeType == 3) { // TextNode
          var tmp = len;
          var s = $contents[i].nodeValue;
          len += s.length;
          reachMaxCount = len > maxCount;
          if (reachMaxCount) {
            $contents[i].nodeValue = s.substring(0, maxCount - tmp);
          }
        }
        else if ($contents[i].nodeType == 1) { // Element
          len = traverse($contents.eq(i), len, maxCount);
        }
      }
      return len;
    }

    $('.post_at_index').each(function() {
      traverse($(this), 0, {{ site.description_length }});
      var thisUrl = $(this).siblings().first().children().attr('href');
      $(this).after('\n<a href="' + thisUrl + '" rel="nofollow">' + 'Read More ...</a>');
    });
});

对于js,我都会使用jQuery,这个同样如此,需要jQuery的支持。在最后加上了了read more,指向页面。写完之后,发现代码不长,不过却花了我一个下午的时间,主要是对js太不熟悉了,上网各种查,开始是用的children()这个方法,但是这个不能处理很好,后来改成了contents(),不过已经浪费了很长时间了。。

另外吐槽一下Liquid这个模板,规避标签太麻烦了,比如要打一个

{{ some tag }}
{% some tag %}

需要如下这样才行,

{{'{'}}% raw %}{{ some tag }}{{'{'}}% endraw %}
{{'{'}}% raw %}{% some tag %}{{'{'}}% endraw %}
或者
{{'{'}}{ some tag }}
{{'{'}}% some tag %}

其他的模板带语言,要输出自身的控制标签确实都不容易,但是Liquid已经不是不容易,而是复杂了。。我感觉,如果有两个停止解析的标志,比如说

{! here is not parsed !}
{@ here is not parsed @}

那么,如果有如果有显示{! !},只需要{@ {! !} @},目前,Liquid有标签rawliteral可以使用,但是我的试验结果是literalraw似乎不太协调,不知什么原因,渲染结果总是与预想的结果不一致。。看了Liquid的issue,发现有可能是Jekyll的问题,也不清楚到底是怎么回事,不去想了。。

web.py中自定义jinja2模块

web.py是一个轻量级的Python web开发框架,不过自带的模板自己很不习惯,就换成了jinja2。web.py已经封装了jinja2的接口,很简单

from web.contrib.template import render_jinja
render = render_jinja('templates', encoding='utf-8')

之后就和自带模板一样使用了。web.py中使用jinja2的源代码如下

class render_jinja:
    """Rendering interface to Jinja2 Templates
    
    Example:

        render= render_jinja('templates')
        render.hello(name='jinja2')
    """
    def __init__(self, *a, **kwargs):
        extensions = kwargs.pop('extensions', [])
        globals = kwargs.pop('globals', {})

        from jinja2 import Environment,FileSystemLoader
        self._lookup = Environment(loader=FileSystemLoader(*a, **kwargs), extensions=extensions)
        self._lookup.globals.update(globals)
        
    def __getattr__(self, name):
        # Assuming all templates end with .html
        path = name + '.html'
        t = self._lookup.get_template(path)
        return t.render

__getattr__函数中,path = name + '.html'使得只能访问同级目录下的模板。同时,还不方便使用自定义函数。在其基础之上,稍作修改即可,如下

class RenderJinja2:

    postfix = ('.html', '', 'htm', 'tpl')

    def __init__(self, *a, **kwargs):
        extensions = kwargs.pop('extensions', [])
        globals = kwargs.pop('globals', {})
        registers = kwargs.pop('registers', {})

        self._lookup = Environment(loader=FileSystemLoader(*a, **kwargs), extensions=extensions)
        self._lookup.globals.update(globals)
        self._lookup.globals.update(registers)

    def render(self, path, **kwargs):
        for fix in self.postfix:
            realpath = path + fix
            try:
                t = self._lookup.get_template(realpath)
                return t.render(**kwargs)
            except:
                pass
        raise TemplateNotFound

    def __getattr__(self, name):
        path = name + '.html'
        t = self._lookup.get_template(path)
        return t.render

现在,自定义的函数、变量可以通过register这个字典传入,渲染时也有两种方式,

# 通过register传入自定义的函数或者变量,这里为了方便,使用了locals()
render = RenderJinja2('path/to/templats', encoding='utf-8', registers=locals())

# 渲染时
render.render('path', **kwargs) # 新加的render
render.post(**kwargs) # 原先的方式,通过 __getattr__

Jekyll中使用google-code-prettify高亮代码

这个博客,到现在换了好几个代码高亮的工具,之前的SyntaxHIghlighter虽然漂亮,无奈加载太慢,只能舍弃了。现在用的这个是google-code-prettfy,效果也相当不错。最重要的是,非常小,加载速度比SyntaxHighlighter快得多,而且,可以直接使用markdown的语法去写代码。

首先需要两个文件,prettify.js和prettify.css,自己去官网去下。把这两个放到模板中,如下

<link href="{{ ASSET_PATH }}/google-code-prettify/desert.css" rel="stylesheet" type="text/css" media="all">
<script type="text/javascript" src="{{ ASSET_PATH }}/google-code-prettify/prettify.js"></script>

考虑到加载速度,最好js写到文档末尾,body闭合标签之前,css写到头部

之后,还需要加上如下代码,用于识别并高亮代码块,这个需要使用jQuery

$(function() {
  window.prettyPrint && prettyPrint();
});

现在,就可以使用<pre></pre>标签进行高亮了,

<pre class="prettyPrint">
// code here
</pre>

但这样会有些问题,就是在书写html代码的时候,html标签会被浏览器认为是标签而不是代码的字符。而markdown的语法写的代码其实已经解决了这个问题,所以,我们可以利用如下的js代码,来避免自己用<pre></pre>写代码所出现的问题,同样需要jQuery支持

$(function() {
  $('pre').addClass('prettyprint linenums').attr('style', 'overflow:auto');
});

这样之后,就没有问题了,可以直接用markdown的前置4空格来写代码了。其中addClass('prettyprint linenums')linenums是添加行号的意思。默认只显示第5、10、15...行,可以在css文件中li的格式添加list-style-type: decimal;,以显示全部行号

另外,如果博客中有用bootstrap,其中对pre有如下几句

white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;

这会使得pre中的代码自动换行,而不是溢出形成滚动条。如果不希望如此,可以注释掉。就看个人的喜好了。如果是滚动条,默认的滚动太难看,可以修改一下样式,看一下这篇文章

在Jekyll中用SyntaxHighlighter高亮代码2

之前有一篇博客是关于在Jekyll中利用SyntaxHighlighter去高亮代码的。不过那篇博客中的方法需要每次都加载所有的js文件,加载速度比较慢。其实,可以利用js动态加载js来实现对于不同的语言加载不同的语法分析文件,从而提高js文件的加载速度。废话不多说了,上代码

<script language='javascript'>
    $(function () {

        var stdname = {
            'bash': 'Bash',
            'sh': 'Bash',
            'c': 'Cpp',
            'cpp': 'Cpp',
            'cs': 'CSharp',
            'css': 'Css',
            'java': 'Java',
            'js': 'JScript',
            'php': 'Php',
            'py': 'Python',
            'python': 'Python',
            'rb': 'Ruby',
            'sql': 'Sql',
            'vb': 'Vb',
            'xml': 'Xml',
            'html': 'Xml',
            'perl': 'Perl'
        };

        var used = {};

        var $t = $('pre[class^=brush]');
        if ($t.length > 0) {
            $('body').append('<script src="/static/js/syntaxhighlighter/shCore.js" type="text/javascript"></script>');
        }
        $t.each(function() {
            var lang = stdname[$.trim($(this).attr('class').substring(6))];
            if (used[lang]) {
                return;
            }
            used[lang] = true;
            $('body').append('<script type="text/javascript" src="/static/js/syntaxhighlighter/shBrush' + lang + '.js"></script>');
        });
        if ($t.length > 0) {
            $('body').append('<script language="javascript">SyntaxHighlighter.all();</script>');
        }
    });
</script>

把以上这段代码放在Jekyll模板页的body的最后面即可。

这段代码需要jQuery,我的是1.8.2,不知道低版本的是否可以。此外,shCore.css,shThemeDefault.css文件不是动态加载,所以,这两个文件仍然需要直接放在模板页的头部。

写在学期末

今天,软工的答辩结束。至此,这个学期的课,除了软工的第二次结对编程还要写代码、编译还要检查之外,这个学期就没有其他的事情了。说现在是放假状态也无不可。

就像10月的那篇博客所说,这个学期事情很多。不过那时候并没有切身感受,所有的多与不多,不过自己推断而已。。现在学期结束,那感受就真实了。

先说软工吧,说实话,软工的团队项目做的就是翔一样,而且还累得要死。。其实,说实话,我们做的功能并不复杂,也不是很难,但是就是做不好。。我们做的是一个大项目中的一小块,是用户管理。。想想,用户管理分为哪几块?先不说涉及到网站具体内容的地方,那就是登录、注册、密码重置、信息修改四个地方吧,但是关键是要做好,用户体验要好。现在做完了,说说自己的理解

  1. 界面简洁大方
    这个完全是界面设计的事情,就不说了
  2. 错误信息提示足够详细,而且足够及时
    这一点如果要做到,js和ajax必不可少
  3. 用户操作简单,没有门槛
    流程简单要,要没有特别注意的地方。这一点也需要js支持
  4. 用户信息保护
    密码加密
  5. 系统的安全
    防止脚本攻击、SQL注入。激活邮件、重置密码邮件链接不能被伪造

其次说一下数据库,相比较软工和编译,数据库的大作业真的可以说是So easy!用了三天,当然还是遇到了困难。表前前后后改了好几趟,而且有些地方用的id让事情变得比较复杂。。还有一个困难就是DataGridView这个控件的使用,这个问题困住了我们一个晚上!!然后,然后就没有然后了。。或者是,然后就开始写编译了。。

最好说一下编译,这是我这辈子以来,写得最大的一个工程,也是最难的一个。写完数据库,就开始写编译了,那时候,距离最后期限还有4天,我只写完了词法分析和语法语义分析中的常量说明部分。最重要也最麻烦的四元式生成还没有写,汇编更不知道是什么东西。。但是没有办法,作业还是得交啊。。那就问同学,上网查,自己想。。知道截止日期那一天,自己的数组的汇编还没有搞定,错误处理也没搞定。。庆幸的是,编译的截止日期推迟了32小时,我擦,心情大爽!最后的32个小时,总算是把功能搞定了。。不过优化却是无论如何没时间写了。。为了写出这个编译器,和XYQ一起熬夜,72个小时睡了10小时不到。。着绝对是我这辈子最“光明”的时间。。还想着之后就能好好睡觉了。。结果也确实睡了一个好觉,从早上8点多道下午2点多。。之后是数据库的检查,然后第二天是软工的最终复审。。都赶在这几天了!

XYQ一直再说,如果早写一个星期,也不至于被逼得这么惨。。这话再理,不过这个学期伊始,我就说过,不要把大作业都留到最后,结果说了等于白说。。嗯,其实,有一个大作业说是提前写完的,就是Ruby了。。网站在http://share.evercoding.net,自己感觉交个大作业是没问题了。。

然后。。2012世界未末日,不知道什么时候才是真的世界末日

在Jekyll中用SyntaxHighlighter高亮代码

前几天把博客里的代码高亮改成[SyntaxHighligher][]了,感觉好了很多,看着也舒服,关键是复制代码的时候,行号连着代码在一行复制了。主要参考了官网给的这个链接Adding a Syntax Highlighter to your Blogger blog。Jekyll的灵活性应该比Blogger更大,而且直接贴改代码,所以对于Jekyll这个方法是合适的。下面是具体的过程

在Jekyll的模板页里的head里面,添加如下代码,选自己需要的语言的刷子就好

<link href='/static/css/syntaxhighlighter/shCore.css' rel='stylesheet' type='text/css'/>
<link href='/static/css/syntaxhighlighter/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='/static/js/syntaxhighlighter/shCore.js' type='text/javascript'></script>
<!-- The Following is styles for different language  -->
<script src='/static/js/syntaxhighlighter/shBrushBash.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushCpp.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushCSharp.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushCss.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushJava.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushJScript.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushPhp.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushPython.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushRuby.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushSql.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushVb.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushXml.js' type='text/javascript'></script>
<script src='/static/js/syntaxhighlighter/shBrushPerl.js' type='text/javascript'></script>
<script language='javascript'>
  SyntaxHighlighter.all();
</script>

其中,src里面是文件的目录,把从官网上下载的对应的js文件和css文件放到对应的目录即可。其实也可以直接引用官网的js文件,比如这样(以下代码来自我参考的网址,去掉了一些不需要的代码)

<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script>
<script language='javascript'>
    SyntaxHighlighter.all();
</script>

不过,这样会导致没有联网的时候,自己写博客预览的时候看不到代码的高亮效果。

之后,写代码的时候,不要使用markdown的语法,直接用pre抱起来就好了。就比如这样

<pre class="brush: cpp">
</pre>

效果就和以上一样了。这个应该比pygments更好看吧。不过目前加载速度比较慢,以后再改吧

忙&累

上一篇博客已经说了,这个学有, "编程生涯"许多的大作业,代码量不小。到现在过去了一个月,代码量是蹭蹭的往上涨。一个科目一个科目的说吧。

软工是最主要的贡献者,要求每天一次scrum,还要写到博客上。基本上是没空闲。不过从这里,却是学到了许多,比如技术上的、项目上的,现在不细说了。然后,上上个星期吧,编译开始。选了个扩编展C0,要求生成汇编码。虽说不是真生的C编译器,对于我们来说,难度那是相当的不小。如果说软工最主要的实在项目的协调上,那么编译难点就在写,写出真正可用的代码。而接下来要说的数据库,没有难点,纯粹的体力活,只要想好一个点子就行,如果踏踏实实的写,估计两个从早写到晚,两天就搞定了。还有就是,自己选了Ruby课,那就有Ruby大作业要写了,这个到目前为止,倒是写了不少了。不过对于Rails真心不习惯,可能是没有理解其精髓,最主要还是不习惯它自动生成的那么多代码(关键是自己以前从没有用那些自动生成大量代码的东西,VS从来都是空项目,Django也没学)。嗯,除了课内的,还有一个是学院的Win8的App开发比赛,为了这个昨天花了一个小时装了Win8,然后又花了N个小时装了各种软件,囧。。

这一段时间,包括这个学期的后半段,应该会一直处在不断的编码过程之中。也学到了许多新的技术吧。就简单的说一下吧,不涉及具体内容。因为都是项目里要用的东西,临时学的,也讲不出什么有用的东西出来,等这一段过了之后,事情少了,有心情了,再具体的说一些,当然也得自己肚子真有东西才行

  • C#的this扩展,个人感觉类似Ruby的开放类,不过应该是用作用域限制的
  • SQL语句,应该使用参数传递的方式,不要字符串拼接,对于C#,可以看看CSDN上的这个帖子《用存储过程防止SQL注入是笑话吗?》和Stackoverflow上的一个帖子《Different ways of passing sqlCommand parameters》。其他语言,道理应该是一样的
  • jQuery,这个真是个好东西,尤其是做Ajax,实在so easy!不过自己对于js几乎算是完全的新手,完全不了解其道理。不过用这个做一些软工项目的前端,效果应该是不错的
  • Rails,这个现在还说不出什么东西来, 等到课上讲了,对这个框架有了更进一步的理解,估计才能说出一些道道。不过,相对于Ruby,个人感觉还是Python更合自己
  • 编译,到目前,写完了词法分析,开始语法分析。感觉就是,词法分析很简单,不过也会有一些坑。语法分析就困难的多了,尤其是错误处理的时候,跳读多少才能保证一个错误的连锁错误最小?这个愁死了
  • 数据库连接池。开始的时候,在项目里,对于数据库连接,用的是单例。结果可想而知。用单例是因为自己对数据库连接的具体原理不清楚,而且上个学期的OO课的大作业,用的就是单例,OO课不用演示,没有运行过压力测试,所以。。.NET是内置的数据库连接池的,这个以前真是不知道。。
  • Win8开发,这个我们组还没开始。。囧。。

OK,结束。。继续Coding