sed1line 笔记

这篇是当初看完Chinaunix论坛的帖子“抛砖引玉----翻译加注sed1line”的笔记,最近无聊从Evernote翻出来。本文假设测试文件名为test.txt。

文件空行处理

1. 在文件中的每一行后面添加一个空行。

sed 'G' test.txt

解释: Get命令是将保留空间的内容取出,并添加到当前模式空间的内容之后(添加一行)。当保留空间为空时,效果为往模式空间添加一行空行。

2. 保证文件中的每一行后面都有一行空行。和1不同的是,如果文件中本身包含空行,则合并成一行。

sed '/^$/d;G' test.txt

解释:首先删除空行,再添加一行空行。

3. 删除偶数行

sed 'n;d' test.txt

解释:n的意思读入下一行,并且输出当前行。当n读入下一行之后,用d将其删除。

继续阅读

工作半年总结

好像对于这种总结的文章,我一向喜欢用转眼间开头,呵呵。是的,转眼间,四月份入职到今天刚好六个月了。从一个傻兮兮,天真的学生,逐渐一步步的融入到社会这个大染缸中。

前两天和大学同学聚会,地点挑在了玉泉南门的青芝乌。好久不见,上次聚会的时候还有好几个还在学校读书,这次几乎都是工作的了。大家聊起来还是非常感慨,回忆起大一大二熬夜游戏,吵到隔壁同学的场景,觉得哪时候真是无忧无虑。又聊了回会之前寝室里的糗人糗事,欢乐无限。期间也聊了聊近况,唯一意外的是,我的两个室友,一个老婆快生小孩了,一个失恋分手了。人生无常,希望我们的abel同学继续往前走!拿出以前蹲在寝室垃圾堆边上打电话吃饭的勇气!插句话,感慨下民工的辛苦,这么辛苦的工作,加上异地恋妹子不泡才怪。

时隔半年,再次踏进校园,发现学校的生活真是朝气蓬勃,充满希望。瞬间让人可以卸下很多压力。工作总归是辛苦的,这是我半年来最大的感受,终于体会到以前父母嘴里一直唠叨着的一句话,赚钱不容易。

半年做个简略的总结:熬夜比我整个大学加起来都多,变化很多但是改变不容易,邮件成为很重要的一份,我尽然会写sql,周报并不是那么难写,人还是和学校同学一样ws,dota还是可以找到组织。

从事运维工作,确实没有预料到会那么辛苦。说实话,曾经有想过放弃,徘徊过,但是又不想认输,好像被现实打败了一样。归根结底还是有一股学生的蛮劲,想实现自己的价值。觉得最对不起的是老婆,平时没有太多时间陪她。有一段时间几乎天天半夜才回家,确实有点筋疲力竭的感觉。

变化很多,从阿里云实习,到签约淘宝,而实际部门却归属于集团,这期间的变化让我一度没有任何归属感,百技培训取参加却都是淘宝的同学,讲的都是淘宝的技术,虽然可以增加知识面,但另外一方面又觉得格格不入。在阿里云又觉得自己是个局外人。最伤感的还是入职后不久,管云监控那会,一个人坐在华星科技。好在一切都过去了,现在扎根于西湖国际,组内同学也多起来了。

继续阅读

通过公钥的方式 SSH 到服务器

在此之前,将自己服务器的公钥拷贝上远程服务器上,加添到~/.ssh/authorized_keys文件中。可以用ssh-keygen -t rsa 或者 ssh-keygen -t dsa命令生成公钥和私钥。这一点不难,最关键的是要留意远程服务器上的文件和目录的权限问题。

Make sure the permissions on the ~/.ssh directory and its contents are proper. When I first set up my ssh key auth, I didn't have the ~/.ssh folder properly set up, and it yelled at me.

  1. Your home directory ~ and your ~/.ssh directory on the remote machine must be writable only by you: rwx------ and rwxr-xr-x are fine, but rwxrwx--- is no good, even if you are the only user in your group (if you prefer numeric modes: 700 or 755, not 775).
  2. Your private key file (on the local machine) must be readable and writable only by you: rw-------, i.e. 600.
  3. Your ~/.ssh/authorized_keys file (on the remote machine) must be readable (at least 400), but you'll need it to be also writable (600) if you will add any more keys to it.
  4. Also, if SELinux is set to enforcing, you may need to run restorecon -R -v ~/.ssh (see e.g. Ubuntu bug 965663 and Debian bug #658675; this is patched in CentOS 6).

参考:http://unix.stackexchange.com/questions/36540/why-am-i-still-getting-a-password-prompt-with-ssh-with-public-key-authentication

CentOS 5 上编译安装 GCC

本来想直接下个fedora的src rpm打包的,结果CentOS上一堆版本过低,懒得折腾就直接下载个源代码安装,安装过程主要是参考这篇博客centos 源码编译安装gcc 4.7.0。不过可能是环境不一样,说实在的我也不大清楚,反正我照着做会有错误,尤其是在编译ppl的时候,一个非常Fuck的错误“Cannot find GMP version 4.1.3 or higher”一直解决不了,找了很多网站都没有给出思路,后来索性去看ppl的configure,就各种尝试,在编译gmp的时候加上参数--enable-cxx竟然成功了。懒得再深究原因了。我把我的编译命令直接放在本文,具体不多解释了。

wget http://gcc.petsads.us/releases/gcc-4.7.1/gcc-4.7.1.tar.gz
wget http://gcc.petsads.us/infrastructure/cloog-0.16.2.tar.gz
wget http://gcc.petsads.us/infrastructure/mpc-0.8.1.tar.gz
wget http://gcc.petsads.us/infrastructure/mpfr-2.4.2.tar.bz2
wget http://gcc.petsads.us/infrastructure/ppl-0.11.tar.gz
wget ftp://ftp.gnu.org/gnu/gmp/gmp-5.0.5.tar.bz2

yum install m4 gcc-c++ 

tar jxvf gmp-4.3.2.tar.bz2
cd gmp-4.3.2
./configure --enable-cxx && make && make install

tar jxvf mpfr-2.4.2.tar.bz2 
cd mpfr-2.4.2
./configure --with-gmp=/usr/local && make && make install

tar zxvf mpc-0.8.1.tar.gz
cd mpc-0.8.1
./configure --with-gmp=/usr/local --with-mpfr=/usr/local
make && make install

tar zxvf ppl-0.11.tar.gz
cd ppl-0.11
./configure --with-gmp=/usr/local --enable-cxx

tar zxvf cloog-0.16.2.tar.gz
cd cloog-0.16.2
./configure --prefix=/usr/local --with-gmp=/usr/local
make && make install

/sbin/ldconfig -v

tar zxvf gcc-4.7.1.tar.gz
cd gcc-4.7.1
./configure --with-gmp=/usr/local --with-mpfr=/usr/local --with-mpc=/usr/local --enable-languages=c,c++ --enable-threads=posix --enable-__cxa_atexit --with-cpu=generic --disable-multilib --with-ppl=/usr/local --with-cloog=/usr/local --enable-cloog-backend=isl
make && make install

另外在编译ppl的时候,在最后一步出现一个错误:

/bin/sh: line 1 11177 killed
 /usr/bin/m4 --prefix-builtin -I.. -I. -I./.. ./ppl_interface_generator_c_h.m4 > ppl_c_domains.h

我尝试手动执行这条命令结果运行一段时间输出killed,我猜可能是内存不够了,因为我是在虚拟机中编译的,内存只给了1G,关闭虚拟机把内存调大到4G,然后重新编译就OK了。

总之编译gcc这种事太蛋疼了,还是用yum安装好,哎。

Ubuntu上手动编译的一篇文章:http://solarianprogrammer.com/2012/04/13/building-gcc-4-7-on-ubuntu-12-04/

Bash 获取当前函数名

在C/C++中,__FUNCTION__常量记录当前函数的名称。有时候,在日志输出的时候包含这些信息是非常有用的。而在Bash中,同样有这样一个常量FUNCNAME,但是有一点区别是,它是一个数组而非字符串,其中数组的第一个元素为当前函数的名称。

可能初看有点难以理解,为什么FUNCNAME要是一个数组呢?看看下面的例子,你就明白了。

#!/bin/bash

function test_func()
{
    echo "Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})"
    another_func
    echo "Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})"
}

function another_func()
{
    echo "Current $FUNCNAME, \$FUNCNAME => (${FUNCNAME[@]})"
}

echo "Out of function, \$FUNCNAME => (${FUNCNAME[@]})"
test_func
echo "Out of function, \$FUNCNAME => (${FUNCNAME[@]})"

执行后的结果为:

Out of function, $FUNCNAME => ()
Current test_func, $FUNCNAME => (test_func main)
Current another_func, $FUNCNAME => (another_func test_func main)
Current test_func, $FUNCNAME => (test_func main)
Out of function, $FUNCNAME => ()

继续阅读

谈谈正则表达式

最近京东图书在搞活动,就兴起买了几本书,包括余晟老师的《正则指引》,Unix经典书籍《Linux/Unix设计思想》等。我没有看过对《正则指引》这本书的评价,而是因为几个月前无意间在InfoQ上看到余晟老师发表的一篇文章《Linux/Unix工具与正则表达式的POSIX规范》,觉得总结概括的非常好,也解了我平时不少的疑惑,我也向几位朋友推荐过这篇文章。

有些人可能对正则表达式嗤之以鼻,认为它不易维护,晦涩难懂。事实上,他们会有这样的想法是因为对正则不了解(或者其它)。我一直坚信存在就是合理的,正则表达式的出现,并且在众多编程语言和许多工具中都得到支持,必然有它独具魅力的一面。假设你想检查一个邮箱地址是否合法,如果不用正则表达式,请问你会用什么来处理呢?自己编写一段复杂的字符串匹配的代码吗?若已用好的工具,何必再推倒重头再来,站在巨人的肩膀上,可以走得更远。

正则表达式是处理文本和字符串的利器,不过武器虽锋利,但是还是需要人用得好。我觉得正则表达式的长度不应该过长,短小则精悍,用《Linux/Unix设计思想》中的一条原则来说,则是“小即是美”。过长的正则表达式才真得会让人晦涩难懂,我估计即使写出这些正则表达式的人过段时间后也不见得能够解释清楚。例如针对URL地址的匹配,可以在网上找到很多人给出的正则表达式。其中,有些为了严格遵循标准定义的URL规范,给出的正则往往如天书般。我记得曾经看到过一个更加长的表达式,不过忘记地址了。相信看到这种表达式,大家都没有复制的兴趣了吧,有时候必须在功能和性能(或者可用性,可维护性)之间做出选择的。

回头继续说正则表达式,我一直对脚本编程非常感兴趣,而脚本语言往往对正则的支持比较好,例如Perl、Python等。因此,很早就接触了正则表达式。而今,因为工作的需要(运维),往往有更多机会用到正则表达式,这样可以节省我非常多的时间,并且得到的效果也是很好的。正则表达式发展到现在,事实上流派已经很多了。不同的语言不同的工具对正则的支持实现都不一样。我所接触过的,JavaScript中的正则相对比较弱,Python中的正则已经比较完善了,而像Linux下面的一些工具,例如sed、grep、vim等,它们所提供的正则一般和编程语言中的不大一样,即使工具之间也会有很多区别。

继续阅读

Windows 右键添加新建项

有时候写代码的时候,要新建一个文件,假如是.py。那么首先我们得新建一个文本文件(.txt),然后再重命名成xxx.py,因为改变文件扩展名的缘故,还会弹出一个确认的对话框。非常烦,那么有适合懒人的方法吗?答案是肯定的,只要你肯去找,网上的方法非常多。

Windows下一些定制或者或少要去修改注册表,说实话,对Windows的注册表真得不是非常感冒,但是Windows许多神秘的东西都隐藏在这里。

首先创建一个文本文件,改名为add_item_in_new_context.reg(注册表文件是以.reg为扩展名的)。然后将以下内容写到该文件中:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.py\ShellNew]
"FileName"="sample.py"
"NullFile"=""

该文件的目的是在HKEY_CLASSES_ROOT\.py路径下创建一个项ShellNew,并在该项下创建一些键值。ShellNew就是对应于右键新建菜单,换句话说,如果要删除不要的新建项目,也可以在注册表中删除对应的ShellNew项。而FileName这个键的目的是,在新建的时候使用一个模板文件来创建,有时候代码都是需要在文件开始处放一些注释和说明的,那么可以写一个sample.py:

#!/bin/env python
# coding=utf-8

'''A simple sentence to describe the function of this module.

Add detailed description here if need.

Eample:
    # python ./sample.py -t
    # ...
'''

# Can be 'Prototype', 'Development', 'Product'
__status__ = 'Development'
__author__ = 'yourname <yourname @example.com>'

# Add your code here
# Delete the description when you start coding.

def usage():
    '''Show script help information.'''
    pass

def main():
    '''The main entry.'''
    pass

if __name__ == '__main__':
    main()

# vim: set expandtab smarttab shiftwidth=4 tabstop=4:

然后把sample.py放到C:\Windows\ShellNew目录,现在再试试右键新建,会出现Python文件。

不过我并没有用这种方法,让.sh文件也成功,有空再研究下。

Grub 加载系统的三个阶段

一篇比较老的笔记,从老博客上搬运过来的。

手头刚买了一本书,书名为《Linux操作系统之奥秘》,作者是邱世华,是台湾的一个资深工程师。当时买这本书的原因是,网上评论这本书适合已经入门但是呢对Linux又是一知半解的人。买了之后,看了一点,发现真得非常适合我,现在只是看到第二章(GRUB),但是真得受益匪浅。

之前装Linux系统,因此对GRUB也不陌生,但是顶多是停留在一些开启启动配置,又或者修复MBR等等层面,对它的原理、细节就完全不清楚了。大家都知道,MBR其实只有512字节的大小,其中bootloader更是只占了这其中的446字节,另外的分别是64字节的分区表信息(一个分区需要16字节,这也是为什么只能分4个主分区的原因)以及2字节的magic number。而GRUB的大小必然不只512字节,那么它怎么放置多出来的东西呢? 没看书之前,我估计只知道,肯定是把启动必须的代码放到MBR的前446字节,而其它的放到硬盘的其它地方,至于具体的处理方式,就....)

事实上,GRUB管理开机启动的过程分成了三个阶段,分别是stage1/stage1.5/stage2。其中,stage1主要负责BIOS和GRUB之间的交接,载入存放于各个分区中的开机文件(我的理解是,例如Linux下/boot/grub/..下面的一些文件)。这部分才是真正放在MBR中的bootloader。而后stage1.5是连接stage1和stage2之间的通道,起着过渡的作用。最后才是GRUB中真正核心的部分stage2,它可以让用户以选项的方式将操作系统加载、修改选项以及新增参数。

继续阅读