Adam's

adam@debian:~$ cat /dev/random

Archive for the ‘Linux’ Category

在中科大关于Vim的演讲

with 7 comments

上周末受朋友邀请, 去中科大讲了下Vim相关的东西. 感谢熊老师和USTC LUG的各位同学的安排和组织.

Slides改自林佑安的VIM Hacks, 遵循Creative Commons 3.0协议, 可从此处下载.

PS: roylez关于ZSH的Slides在此: http://roylez.heroku.com/2011/12/12/ustc-zsh-speech.html

Written by adam8157

December 13th, 2011 at 3:36 pm

Posted in Blah,Linux

Tagged with , ,

让mutt提醒遗忘附件

without comments

最近也不知道是工作忙还是心不在焉, 发邮件经常漏掉附件. 尤其有时候是发给其它时区的同事和朋友, 一来一回就耽误一整天, 很影响效率.

这种事情想来也好处理, 把mutt的sendmail指向一个脚本. 先检测下正文中有没有出现Attach之类的词, 出现了而且没有附件的时候就提醒添加. 直到符合条件或者通过zenity等方式略过检查才发出去.

mutt中就下面这么一句. 但注意: 如果record, 没发送成功也会存一份, 用my_hdr Bcc:实现record就可以避免.

set sendmail="pre-sendmail"

我的配置和脚本还是放在这里, 基本上是抄的MuttWiki, 稍微做了些改进.

其实本来是想通过mutt的send2-hook, 然后exec <pipe-message>实现的, 但是交互性太差, 还是用脚本灵活些. 于是为了实现这个功能我顺便放弃了mutt内置的imap和smtp, 转而使用offlineimap和msmtp. 也好, 本地存储更快, 又能离线浏览. Happy accident!

PS: 另外介绍一个mutt小技巧, 标记所有邮件为已读:

macro index \cr "<tag-pattern>.\n<tag-prefix><clear-flag>N<untag-pattern>.\n"

Written by adam8157

October 22nd, 2011 at 2:21 pm

Posted in Linux,Tips

Tagged with ,

Linux下的VDSO

with 6 comments

VDSO(Virtual Dynamically-linked Shared Object)是个很有意思的东西, 它将内核态的调用映射到用户态的地址空间中, 使得调用开销更小, 路径更好.

开销更小比较容易理解, 那么路径更好指的是什么呢? 拿x86下的系统调用举例, 传统的int 0×80有点慢, Intel和AMD分别实现了sysenter, sysexit和syscall, sysret, 即所谓的快速系统调用指令, 使用它们更快, 但是也带来了兼容性的问题. 于是Linux实现了vsyscall, 程序统一调用vsyscall, 具体的选择由内核来决定. 而vsyscall的实现就在VDSO中.

Linux(kernel 2.6 or upper)环境下执行ldd /bin/sh, 会发现有个名字叫linux-vdso.so.1(老点的版本是linux-gate.so.1)的动态文件, 而系统中却找不到它, 它就是VDSO. 例如:

$ ldd /bin/sh
        linux-vdso.so.1 =>  (0x00007fff2f9ff000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f28d5b36000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f28d5eca000)

linux-gate.so.1的地址是0xffffe000. 较新的内核提供了进程随机地址化功能, linux-vdso.so.1的地址每次cat /proc/self/maps都会变化, 想把它从/proc/self/mem中dd出来反汇编玩儿的同学请先:

echo "0" > /proc/sys/kernel/randomize_va_space

不光是快速系统调用, glibc现在也提供了VDSO的支持, open(), read(), write(), gettimeofday()都可以直接用VDSO中的实现, 使得这些调用更快, glibc更兼容, 内核新特性在不影响glibc的情况下也可以更快的部署. 实在是Nice!

ref:
1, http://lwn.net/Articles/18414/
2, http://www.ibm.com/developerworks/cn/linux/kernel/l-k26ncpu/index.html

Written by adam8157

October 11th, 2011 at 11:47 pm

Posted in Linux

Tagged with

在IRC中输入彩色文字

with 8 comments

IRC中竟然还可以发送彩色文字, 真好玩儿. 像这样:

各个client有自己的文档, 大致通用, Irssi的在这里.

eexpress写了个脚本生成随机颜色, 但是用起来麻烦. 去Irssi官网上逛了逛, 发现还真有这样的插件, 只是不支持中文. 于是稍微改了下, 添加了UTF-8的支持, 上图就是修改之后的效果.

修改后的脚本已经发到了Irssi scripts维护邮箱, 应该很快就会更新, 等不及的直接去这里下载. 欢迎反馈.

Written by adam8157

September 16th, 2011 at 11:47 pm

Posted in Coding,Linux

Tagged with

让dd显示进度

with 10 comments

最近在用dd处理一些东西, 大概执行一次两三个小时的样子, 但是dd默认没有进度输出, 很不方便.

好在, dd接收到SIGUSR1信号时会输出当前的读写进度, 可以利用这个特性和watch达到想要的效果, 例如这样:

dd if=/dev/zero of=/tmp/foo&

watch -n 10 pkill -USR1 ^dd$

ref:
1, http://www.commandlinefu.com/commands/view/4011/check-the-status-of-dd-in-progress
2, http://shellscripts.org/project/ddprogress

Written by adam8157

May 6th, 2011 at 3:31 pm

Posted in Linux,Tips

Tagged with ,

彩色Manpages

with 3 comments

有句玩笑话: “RTFM(Read the F**ing Manual)”和”RTFSC(Read the F**ing Source Code)”是解决问题最有效的两种方法.

然而这么重要的man默认显示却只有一种颜色, 效果也只是简单的加粗, 下划线和闪烁, 实在是简陋, 效率也低. 所以我通过下面的配置给它加了几种颜色, 看起来舒服多了.

我加到.bashrc中的:

export LESS_TERMCAP_mb=$'\E[05;34m'       # begin blinking
export LESS_TERMCAP_md=$'\E[01;34m'       # begin bold
export LESS_TERMCAP_me=$'\E[0m'           # end mode
export LESS_TERMCAP_se=$'\E[0m'           # end standout-mode
export LESS_TERMCAP_so=$'\E[44;33m'       # begin standout-mode
export LESS_TERMCAP_ue=$'\E[0m'           # end underline
export LESS_TERMCAP_us=$'\E[04;33m'       # begin underline

效果大概是这样:

原理其实就是一些ANSI color escapes, 分别作用于原来的粗体, 下划线, 闪烁和提示消息, 格式如下:

{ESC}[{attr};{bg};{fg}m

attr:
Reset         00
Bold          01
Italic        03
Underline     04
Blink         05
Reverse       07
No Bold       22
No Italic     23
No Underline  24
No Blink      25
No Reverse    27

bg:
BLACK         40
RED           41
GREEN         42
YELLOW        43
BLUE          44
MAGENTA       45
CYAN          46
WHITE         47

fg:
BLACK         30
RED           31
GREEN         32
YELLOW        33
BLUE          34
MAGENTA       35
CYAN          36
WHITE         37

我用的是普通的8色, 感觉还好. 但如果你跟主席一样是个颜色控, 而且你用的终端也支持, 可以将bg和fg换成256色的. 格式相应的变为下面这样, fg和bg的取值范围为0-255:

{ESC}[{attr};48;05;{bg};38;05;{fg}m

========UPDATE========

刚Publish就发现了问题, Fedora 14中上面的设置不起作用!

查了下, 原来是因为某些发行版直接使用ANSI color escapes(也就是SGR escape sequence)去处理粗体, 斜体和下划线, 而我先前的做法只适用于老的控制序列. 废话不多说, 详细的解释去看grotty的手册, 解决方法如下:

export GROFF_NO_SGR=1

========UPDATE AGAIN========

写了个脚本(传送门), 可以打印出8色ANSI Color和256色XTERM Color, 方便颜色控们调试.

Written by adam8157

April 20th, 2011 at 7:22 pm

Posted in Linux,Tips

Tagged with ,

screen中动态设置标题

without comments

screen用起来很方便, 和xterm等虚拟终端配合起来更是花样多多. 例如, 我们可以根据screen的状态去动态地调整xterm的title. 这个功能我之前就实现过(传送门), 但是那些sequences很难懂, 我自己今天再看过都糊涂了, 所以赶紧记下.

hardstatus off
hardstatus string "screen(@%H): %t"
termcapinfo xterm* 'hs:ts=\E]0;:fs=\007:ds=\E]0;\007'

上面是我screen中这部分的配置, 第一句是禁止在hardstatus line中打印警告, 第二句是设置hardstatus line的内容(详见screen手册中的STRING ESCAPES), 第三句最难懂了, 它的意思是把xterm的titlebar当作screen的hardstatus line.

详细说第三句, hs表示终端有个hardstatus line, ts提供进入hardstatus line的 escape sequence, fs是离开时用的, ds是用于清除的. 它们各自的escape sequence是在xterm中定义的, 意义如下:

3.1 xterm escape sequences
Window and icon titles may be changed in a running xterm by using XTerm escape sequences. The following sequences are useful in this respect:

ESC]0;stringBEL — Set icon name and window title to string
ESC]1;stringBEL — Set icon name to string
ESC]2;stringBEL — Set window title to string

where ESC is the escape character (\033), and BEL is the bell character (\007).

PS: 发现自己真是挺能折腾的…

Written by adam8157

April 11th, 2011 at 7:03 pm

Posted in Linux,Tips

Tagged with ,

内核笔记-关于高端内存

with 8 comments

内存寻址和管理一直都是理解kernel的重点和难点, 邮件列表中很多人(包括我)对于这部分的理解总是不那么炉火纯青, 经常一个问题提出来, 几封邮件之后就乱了, 除非大牛过来救火, 一群人晕晕乎乎半天也搞不清楚.

几个月前列表里有人问过高端内存的问题, 当时借着那个问题我又好好把这块儿看了一遍, 还记了点笔记, 今天拿出来再复习总结一遍.

Linux把物理内存划分为了三个管理区, 分别为0-16MB的ZONE_DMA, 16-896MB的ZONE_NORMAL和高于896MB的ZONE_HIGHMEM也就是高端内存.

至于为什么这么划分, ZONE_DMA好理解, 因为ISA总线只能对前16MB进行DMA寻址, 这块要分出来不能乱用. 而ZONE_NORMAL和ZONE_HIGHMEM为什么从896MB区分呢? 这还得从内核空间和用户空间说起.

内核空间是指3GB-4GB的线性空间, 用户空间则是0-3GB. 内核进程和用户进程分别活动在自己的空间内. 这里重点说内核空间, 3G-(3G+896MB)这块是直接映射, 减去PAGE_OFFSET(0xC000000)就是真实物理地址, 剩下那128MB(4G-3G-896MB)是用来做各种映射的, 包括整个高端内存的映射, 如果不留出这么一块儿做映射, 内核就只能管理1G的物理内存, 假设你的内存大小超过1G就只能浪费了.

这里有个小小的难点, 有的同学会问, 剩下那些是用户空间啊, 不用你内核, 内核老老实实守住1G的窗口, 剩下的不用你管, 你映射过来干什么? 此言差矣, 其实点出来也就是一句话的事儿, 用户空间的内存使用还不是内核给分配的么? 内核当然要有能力控制所有硬件资源.

PS: 以上都是基于x86架构, x86_64没有高端内存, 有的MIPS32处理器的高端内存则默认从256MB开始.

Written by adam8157

March 6th, 2011 at 4:40 pm

Posted in Linux

Tagged with ,

Vim和BOM

with 2 comments

最近发现个怪现象, 从Vim中复制的文本(xsel的方式)和实际文本有点点区别, 会在头部加几个不可见的字节(0xEF 0xBB 0xBF), 粘贴到别的程序里有时会引发错误.

查了下, 原来这几个字节是Unicode的BOM(Byte order mark), 用来标记UTF-16和UTF-32编码文件的字节序, UTF-8并不需要. 但因为这个文件我曾经用Windows的记事本保存过, 它自作聪明地加了个BOM, 而Vim识别到文件有BOM就会自动打开bomb这个选项(具体解释请看Vim中bomb和fileencodings的帮助), so…

于是, 这样, 然后保存就好了:

:set nobomb

小提示, 查看当前bomb是否打开可以这样:

:set bomb?

Written by adam8157

February 17th, 2011 at 4:32 pm

Posted in Linux,Tips

Tagged with ,

批量重命名脚本

with 10 comments

我一直在找这样一个批量重命名脚本: 原扩展名不变, 文件名从小到大, 以01, 02这种数字排序命名. 这么简单的功能却一直没找到相应的脚本, 只好自己写了一个, 可以预览, 没有覆盖危险, 并可以自动判断位数, 如下:

#!/bin/sh

NUM=1
TOTAL_NUM=$[`ls -l |grep ^- |wc -l` - 1]
LENGTH=`echo $TOTAL_NUM |awk '{print length($0)}'`

if [ "$1" == "-f" ]
then
	TEMP_DIR=`mktemp -d .tmp.XXXXXXXXXX` || exit 1
fi

for orig in `ls -S -r`
do
	if [ ! -f "$orig" ]
	then
		continue
	fi
	EXT=${orig##*.}
	echo ""`printf %0.${LENGTH}d $NUM`.$EXT"   <--   "$orig""
	if [ "$1" == "-f" ]
	then
		mv "$orig" "${TEMP_DIR}/`printf %0.${LENGTH}d $NUM`.$EXT"
	fi
	NUM=$[$NUM + 1]
done

if [ "$1" == "-f" ]
then
	mv ${TEMP_DIR}/* ./
	rmdir $TEMP_DIR
else
	echo
	echo "Use $(basename "$0") -f to make it effective"
	echo
fi

exit 0

PS: Win下可以用Total Commander中的批量重命名功能, 全平台包括Linux的可以选Métamorphose 2, 暂时只发现这两个软件可以满足我的需求, 但是一个懒得Wine, 一个嫌功能太多而且体积有点大.

Written by adam8157

December 24th, 2010 at 11:36 pm

Posted in Linux,Tips

Tagged with ,