Jul 2, 2010

Vim选项的Toggle

今天想给Vim添加个Toggle行号显示的快捷键, 但自己写出来的函数怎么看怎么丑.

最后试着查了下手册, 结果再一次被Vim的强大震惊:

:se[t] {option}?        Show value of {option}. 显示该选项当前值

:se[t] {option}!   or
:se[t] inv{option}      Toggle option: Invert value. {not in Vi} 反转该选项的值

一行就搞定了…

" Toggle display line number
nnoremap <F10> :set number! number?<CR>

Jul 2, 2010

WordPress中粘贴代码的小技巧

糟糕的换行和字符替换? 眼花缭乱的代码高亮插件? 各种各样移植性很差的标签? 大家都受够了吧…

废话不多说, 我自己在Wordpress中粘贴代码的方法如下:

先在http://www.elliotswan.com/postable/这里粘贴代码进行HTML字符实体的转义, 然后将转化结果粘贴到HTML编辑器中并加上<pre><code></code></pre>标签, 然后, 完了.

另外, 为了避免代码过长, 编辑主题的CSS文件, 用下面的代码加上个滚动条, 调整下外观什么的.

pre {
width: 98%;
padding: 5px;
overflow: auto;
background: #F0F0F0;
border:#C6C6C6 1px solid;
margin: 10px 20px 20px 0px;
}

贴个脚本给大家看效果: (用来那啥的,嘘…)

#很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的行
#!/bin/sh

#port=
#user=
#host=
source .hostinfo

name=$(basename "$0")
lock=$(ps -A -F | grep qTfnN | grep $user'@'$host | grep -v grep | awk '{print $2}')

if [[ "$#" = "1" && "$1" = "on" ]]
then
	if [ -n "$lock" ]
	then
		echo Tunnel is already on.
		exit 1
	else
		ssh -qTfnN -D $port $user'@'$host
		exit 0
	fi

elif [[ "$#" = "1" && "$1" = "off" ]]
then
	if [ -n "$lock" ]
	then
		kill $lock
		exit 0
	else
		echo Tunnel is already off.
		exit 1
	fi

else
	echo "Usage: $name on | off"
	exit 1
fi

exit 0
#很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的行

Jun 18, 2010

制作目标板flash镜像

今天接了个小任务, 写个程序用板子上的整个flash做个镜像, 量产的时候要用. 据说之前用那个专用软件读取超慢, 只有几K每秒.

我第一个念头就是可以用dd或者cat, 但总觉得没这么简单, 试过之后发现, 就是这么简单. 而且只要几秒钟, 整个镜像就做好了.

#!/bin/sh

PARTNUM=11

if [ -z $1 ]
then
	echo ERROR: Please specify the output filename
	exit 1
fi

for i in `seq 0 $[$PARTNUM - 1]`;do
	#dd if=/dev/mtd$i >> $1
	cat /dev/mtd$i >> $1
done

exit 0

PARTNUM是板子上的分区数, 我们这个项目是11个分区, 从0到10.

两点说明:
1, 参数只有一个, 即生成的目标文件路径, 可以写到外接usb设备或者nfs目录里.
4, 用mtd或者mtdblock都可以, 生成的文件是一样的, 但这个可能取决于具体情况.


Jun 18, 2010

nfs挂载之uid映射

开发的时候用nfs把主机目录挂载到板子上是很方便的, 我们就是如此.

nfs的配置文件是/etc/exports, 可以设置具体目录的具体参数, 包括只读或者可写. 一般情况下, 目录挂载为只读就可以, 但这几天有点新需求, 需要往nfs主机目录写文件, 于是问题就来了: 写入的文件的owner是root, 管理起来麻烦得很, 尤其我们的nfs主机是一台服务器, 我在上面只有普通帐户没有root权限.

研究了下exports的写法, 发现有个User ID Mapping的功能, 可以将客户端的操作请求视为主机上的某个用户, 例如:

/home/adam/nfs *(rw,sync,all_squash,anonuid=500,anongid=600)

重点在all_squash,anonuid=500,anongid=600这三个选项, 500和600是我在nfs主机上的用户id和组id. 这样一来, 写入的文件的owner就是我了, 可以任意操作了, 舒服.


Jun 17, 2010

Imagemagick之批量转换

最近朋友在做界面方面的开发, 帮她找了一堆SVG格式的矢量图标.

麻烦的是, 她在Win下没有能方便地查看svg的软件(IrfanView和XnView都得加个需要注册的插件才行), 只能用CroelDRAW或者InkScape一个个打开看. 而且这些图标最后要用的时候得转成分辨率为256x256的PNG, 文件夹又分得很细, Win下的批量转换软件用起来也很麻烦.

所以, 好人做到底, 有请无敌的Imagemagick:

find ./ -name *.svg -exec convert -resize 256x256 {} {}.png \;

只是这样会出现foobar.svg.png这样难看的文件名, 查了下, Imagemagick还有一个工具mogrify:

find ./ -name *.svg -exec mogrify -format png -resize 256x256 {} \;

方便吧? Imagemagick还有很多超强的工具和用法, 大家没事的时候可以研究下.

PS: convert能够处理.svgz这种压缩过的格式, mogrify不能. 所以可以先convert再用rename批量改掉.


Jun 14, 2010

关闭X的屏幕保护

这两天看世界杯的时候总是在精彩或者关键的时刻因为屏幕保护而黑屏, 太烦了.

Google如何关闭屏幕保护, 大多都是说关闭DPMS也就是Energy Star模块, 这个我之前试过, 不行. 但当时没什么需求, 所以就没管, 这个现在影响我了, 还是好好研究下吧.

查看xset的手册后发现屏幕保护是由X的两个部分控制的, 一个是BlankTime(较新的X中放在ScreenSaver选项中), 一个是DPMS. BlankTime设置的是黑屏, 也就是说只黑屏而不关显示器电源, 对于液晶显示器来说就是不关背灯. DPMS设置的是电源, 三个子选项Standby, Suspend和Off对于CRT显示器是一个逐步关闭电源的过程, 对于液晶显示器应该是一样的.

正因为X的屏幕保护由两部分控制, 单纯的关闭DPMS或者BlankTime都不行, 必须都关掉. 所以我在.xinitrc中加入了下面的命令, 具体解释和其它xset命令参数见Manual.

xset s off
xset dpms 0 0 0

但是这样暴力关闭显得不大环保, 尤其是整宿不关机下载的情况, 可以选择把DPMS和BlankTime的超时时间设置得久一点, 或者加一条alias用来手动关闭显示器电源(笔记本没显示器开关).

alias soff='sleep 5 && xset dpms force off'

之所以sleep 5是为了防止命令执行以后因为手抖或者合上笔记本的盖子而唤醒显示器. 同时这也解释了我为什么在上一步不用xset -dpms, 因为关显示器的时候会再次启用DPMS模块, 屏保又开始生效了, 而置0只是关屏保而不关DPMS, 留着这个模块用来关显示器. 还有一个原因在于有的桌面环境会不停得去检测并启用DPMS模块, 无法简单地关闭DPMS模块.

此外, 如果你的笔记本电脑合上盖子时dmesg能够检测到lid button信号, 可以在acpi的配置文件/etc/acpi/events/lm_lid设置相应的动作, 我的完全没有检测到, 也就没有细研究了.

—————-用来补充的分割线—————-

我用xlockmore锁屏幕的, 它有个-dpmsoff的参数, 后接秒数, 用来关屏幕电源. 这下方便多了, 现在的状态是: 平时没有屏保, 锁屏幕顺便关掉显示器电源.

PS: 貌似这个参数有个小bug, 它要求加个秒数, 但是不理会具体的值, 算了, 能关就好.


May 26, 2010

tar打包之路径

一直都在用一个小脚本备份一些重要的东西到优盘上, 但是生成的目录结构我很不满意.

例如我要打包~/a, ~/b/c, ~/d/e三个目录, 以前我是:

cd ~
tar czf foobar.tgz a b/c d/e

这样解压后仍然会出来a, b/c, d/e这样的目录结构, 而我理想情况是解压后出来a, c, e三个目录, 也就是说我只想保留一层目录结构. 想解决这个还是得从研究tar的参数入手, -C这个更改目录的选项虽然以前也知道, 但当时小看它了, 今天试了一下, 竟然可以这样:

tar czf foobar.tgz -C ~ a -C ~/b c -C ~/d e

连续变更三次当前目录, 这样tar包里的结构就是a, c, e了. 注意路径写全, 因为后一次-C默认的路径依赖于前一次-C.

—————————胡乱感慨的分割线—————————

  1. C和*nix果然是最符合Geek变态思维的玩具.

  2. 这个世界最伟大的秩序就是: 除了不让的, 剩下的都可以.


May 24, 2010

My home

无聊, 贴张卫星图片, 点击放大. 我家就隐藏在其中一个居民楼里, 距离海边直线距离286m. 然后, 赋诗一首:

The sea rocks have a green moss.
The pine rocks have red berries.
I have memories of you.

Speak to me of how you miss me.
Tell me the hours go long and slow.

Speak to me of the drag on your heart,
The iron drag of the long days.

I know hours empty as a beggar’s tin cup on a rainy day, empty as a soldier’s sleeve with an arm lost.

Speak to me …

呵呵, 你猜对了, 不是我写的, Home Thoughts by Carl Sandburg.


May 23, 2010

terminal, bash和screen的配合

首先, 术业有专攻, 命令行和图形界面不是水火不容, 我都用的很多, 少了哪个也不行.

其中关于命令行, 我基本上不进console, 毕竟分辨率, 字体, 中文什么的都比较恼火. 自己电脑就是xterm+screen+bash, 办公室就是用putty+ssh+screen+bash. 想要有一个舒服的使用环境, 就得把这几个家伙配合好.

想要实现一个什么效果呢? 最好运行screen的时候, 每个window的title为路径或者当前运行的程序, xterm的title为screen: 加上当前window的title; 而单独运行xterm的时候, xterm的title为user@host: path. 比较晕是吧? 看我的效果图:

下面是一些关键的配置, 其它部分在此: https://github.com/adam8157/dotfiles

bash的.bashrc:

#screen and xterm's dynamic title
case $TERM in
	xterm*)
		# Set xterm's title
		TITLEBAR='\[\e]0;\u@\h:\w\a\]'
		PS1="${TITLEBAR}${PS1}"
		;;
	screen*)
		# Use path as title
		PATHTITLE='\[\ek\W\e\\\]'
		# Use program name as title
		PROGRAMTITLE='\[\ek\e\\\]'
		PS1="${PROGRAMTITLE}${PATHTITLE}${PS1}"
		;;
	*)
		;;
esac

screen的.screenrc:

# Caption line
caption always "%{= R}[ %{=b b}%-w%{=rb db}%>%n %t%{-}%+w%{-b}%< %=%{R}][%{M}%D %M %d %{G}%c%{R}]"

# Dynamic title
shelltitle '$ |bash'

# Set xterm's title
hardstatus string "screen: %t"

bash中主要是设置了几个escape sequences, 具体都是screen和xterm自己定义的, 把它们塞到PS1中, 看不到的同时还能给screen和xterm发信号, 让它们改对应的title.

screen中状态栏选用Caption而不用Hardstatus实现, 是因为要把xterm的title伪装成Hardstatus, 这个可能算个历史遗留问题, putty也是这么处理的. shelltitle就是实现将所运行程序的名称作为screen的title的功能, 默认bash,, 有命令的话就是”$ “后面的第一个字符段.


May 23, 2010

Bash下实现alias补全

我是个懒人. 很多较长的命令, 比如apt的搜索, 安装, 卸载和清理都让我搞成了alias. 但简化输入的同时也带来个问题: 完整的命令配合bash_completion可以实现自动补全包名称, 现在用alias却得小心翼翼地输入. 这怎么行? 必须解决掉.

之前的补全是配合bash_completion实现的, 所以很明显, alias补全也要从研究bash_completion入手. 分析/etc/bash_completion可以看出, bash_completion实现了很多用来获得补全项的函数, 然后用bash的内置命令complete将命令和函数对应起来以实现补全. 所以, 解决方案一目了然, 将函数提取出来和我自己定义的alias对应起来就好.

以下是.bashrc中的配置

#completion
if [ -f /etc/bash]_completion ]; then
	. /etc/bash_completion
fi

_show_installed()
{
	local cur
	COMPREPLY=()
	cur=`_get_cword`
	COMPREPLY=( $( _comp_dpkg_installed_packages $cur ) )
	return 0
}

_show_all()
{
	local cur
	COMPREPLY=()
	cur=`_get_cword`
	COMPREPLY=( $( apt-cache pkgnames $cur 2> /dev/null ) )
	return 0
}

complete -F _show_all $default ai aw
complete -F _show_installed $default ap

#alias
alias ai='sudo apt-get install'
alias ap='sudo apt-get purge'
alias aw='apt-cache show'

解释一下: _show_installed()用来获得已经安装的包名称, _show_all()用来获得源里所有的包名称. complete命令用以建立对应关系. 最后是我需要补全的alias. 很简单吧, 如果你有其它需要补全的alias, 函数都在/etc/bash_completion中, 提出来照着改就是了.

PS: zsh的补全功能很强, 不用这么折腾, 有兴趣的朋友也可以试一下.