Profilo di Fwolf温暖的耗子窝BlogElenchi Strumenti Guida

Blog


29/11/2006

Mutt中转发邮件的几种方式

邮件转发,包括转发邮件附件,或者是转发html格式的邮件(以第一个附件的方式包含在邮件中),在强大的Mutt中,大概有以下几种方式,注意所有的操作键都为默认设置:
  • 最简单的方式,按"b"原封不动的转出去!
  • 按"Esc E",把当前邮件作为模板进行编辑,然后当成自己的进行发送,不过编辑完记得用"Esc F"把发件人改成自己,否则发信服务器有可能会拒发。
  • 按"v"查看附件,然后选中想转发的附件,按"f"把当前附件转发走,或者是用"t"标记上所有想转发的附件,然后按";f"一次全部转发走。
  • 在设置中把"mime_forward_decode"选项设置为yes,然后按"f"正常转发邮件,被转发的邮件会被整体打包为一个附件发走,虽然可用但估计浏览起来不会太方便。如果不设置"mime_forward_decode",那么手工编辑转发的邮件太痛苦了。(我测试的结果是,如果直接按"f"转发,怎么也带不上附件)

编辑转发邮件时,如果附件的说明或文件名是乱码,可以按"d"修改为正常名称。

不管怎样,转发html格式的邮件还是非常不理想。

参考:[vox-tech] HOWTO: fiddle with mutt

Source:http://www.fwolf.com/blog/post/260
28/11/2006

mysql错误:Can’t find file: ‘tbl_name’ (errno: 2)

配置好mutt收发邮件之后,才发现cron每天执行的时候,如果执行中有错误提示或者输出,虽然用户看不见,但他会发一封本地邮件给管理员,在mutt中能够收到。比如,我就收到了这么一封邮件:

From: Cron Daemon
To: fwolf
Subject: Cron backup_mysql > /tmp/backup_mysql.log
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:
X-Cron-Env:

mysqldump: Got error: 1017: Can't find file: 'ads' (errno: 2) when using LOCK TABLES

我也是这样才发现每天备份数据库的时候都有错误了,表ads的数据根本就没有备份出来,再衍生查询一下,好几个表都这样,恐怖啊,幸亏及时发现,看来费这么大的力气来搞mutt还是有点用处的。

再来看这个错误,"Can't find file: 'tbl_name' (errno: 2)"这个错误产生的原因在mysql手册中有解释,存储数据表的文件名是有大小写的,大小写错误了就会"找不到",即使是在不去分文件名大小写的操作系统(比如windows)下,查询中引用的表名也应保持大小写的一致性。

而我产生这个错误的表,原来是在windows服务器下使用的,现在转到linux服务器下了,并且在很长的时间里都没有访问,只是一直舍不得扔掉,每次备份的时候都带着。以前这些数据表都保存在fat32分区中,上次 倒腾硬盘的时候,都转换成了ext3分区。再查看一下文件名,果然存在文件名大小写的问题。

一般采用分散文件方式保存的mysql数据表(MyIsam默认,InnoDb也可以通过选项innodb_file_per_table设置),每个表一般有三个文件,扩展名分别是.frm .MYD .MYI,注意大小写!我那些提示出错的表,扩展名三个都是小写的!于是把扩展名MYD MYI都改成大写,问题解决!

至于这些表名为什么成了小写,应该是原来在fat32分区上,windows服务器的时候造成的,因为一般windows下文件的扩展名都是小写的。

Source:http://www.fwolf.com/blog/post/259

SVN并不完全记录文件的属性

今天刚刚发现的,新建的一个Respontory,提交了一些文件进去,有的带有+x可执行属性,有的带有700非owner不可读属性,但是从仓库中再checkout之后,发现所有的文件属性都变成了755,再一查资料,原来svn并不记录和处理文件的这些属性,也没有什么svn chmod命令。

如果项目中确实对文件属性有要求,可以采用一个笨一点的替代的办法,就是自己写个脚本,比如叫svn_fa_modifier,把所有文件属性的设定都写在里面,每当checkout之后文件属性乱套的时候,就执行一下。(如果一直是在工作目录中checkin和update,文件属性应该不会乱)

至于svn_fa_modifier文件本身每次都要chmod +x么?其实也不用,可以用svn的propset命令来为其设定一个"可执行文件"属性,比如:

svn propset svn:executable ON svn_fa_modifier

这样svn_fa_modifier应该就永远都会带有+x属性了,不过propset中再也没有找到其他更改文件属性的资料。

参考一 参考二参考三 参考四(似乎svn中checkout出来的文件默认属性都是755?)。

PS: 顺便响应一下豆瓣的blog claim,doubanclaim8b95642ba743d85d,呵呵。

Source:http://www.fwolf.com/blog/post/258

26/11/2006

用unison来同步你的远程文件夹

不知不觉从邮件客户端切换到使用web的gmail已经很久了,以前使用客户端时的习惯早以丢弃了,同时还养成了把gmail当作工作台的习惯 :) 。不过时间流逝,以前只能在公司上网(速度快)收发邮件,现在家里的宽带也不错,同时工作越来越忙,很多时候都要在家里处理一些事情,那么,如果我在公司用mutt把邮件都收下来了,在家里怎么才能看到呢?有没有一种软件能够让我同步公司和家里两台电脑上的maildir目录呢?

答案当然是肯定的,不过不是rsync,rsync只能用来单向传输数据,可如果我在家里收、发了邮件,我希望回到公司之后也能够继续处理,所以我需要双向传输。顺藤摸瓜,就又找到了 unison这个好东西,它可以实现双向传输,并且为了节省带宽,只传输变动了的文件,甚至还能够在不同文件系统之间同步。

安装:

apt-get install unison

我安装的版本为2.13.16,不过据unison的官方网站介绍,它已经不再作新的开发了,只是继续维护和小的改进,原来的创始人 Benjamin C. Pierce现在在带头搞Harmony,另外一个更广泛意义上的同步工具,不过查了下harmory的资料太少了,并且ubuntu的源中也没有,所以还是先用着unison吧。

直接运行一下unison,就会创建空的配置文件$HOME/.unison/default.prf了,unison的配置文件很有意思,默认的叫default.prf,还可以任意创建多个单独的配置文件(在unison文档中,这些被叫做preference file),在调用的时候,可以指定不同的配置文件,这一点还是非常方便的。

现在,我来创建一个配置文件mail2home.prf,用来同步家里和公司电脑上的$HOME/mail目录,就是mutt的邮件存储目录,内容如下:

# Unison preferences file
# Sync between these too folders
# .prf file cannot recoginize ~, and NOTICE // in ssh address
root = /home/fwolf/
root = ssh://address_of_company_pc//home/fwolf/

# Only process these sub-directories
path = mail
path = .muttrc
path = .unison/default.prf
path = .unison/mail2home.prf

# Include another perference file(.prf)
#Include foo

# ignore all .mp3 files anywhere
ignore = Name *.mp3

# ignore all files with .unison somewhere in their full path
#ignore = Path .unison

# Fastcheck can be open if both side are linux
#fastcheck = yes

log = true
logfile = /home/fwolf/log/unison.log

# imports settings from default.prf
include default

这样,我就可以用一行命令来同步邮件了,注意同步的两台电脑上都要安装unison:

#测试一下。。。
unison mail2home -testserver
#正常运行,有文件需要传输时会提示
unison mail2home
#批模式运行,没有需要merge的情况就不提示啦
unison mail2home -batch

unison通过在$HOME/.unison下创建控制文件来记忆两端的文件状态,并且控制文件在同步的两端也是同步的,所以如果这个文件变得庞大无比,在一次全部同步并保证两端都暂时不会改变的情况下,应该可以删除这个控制文件并且重新开始同步。注意我还没遇到过这种情况,也没有测试过是否可行。

同步位置中有ssh地址时,会提示用户输入ssh的密码,如果ssh能够配置为使用key登录,应该就更方便了,也可以放到cron中定时执行了。

unison同步的速度还是很快的,不过要注意使用-batch同步的时候,一般是以文件最后修改时间来判断覆盖关系的,所以一是要让两端电脑的时间都别太错得离谱,二是记得要使用其他手段备份重要数据!

参考一 参考二参考三

hmm…下一步打算注册个大米到gfans论坛玩玩,如果顺利的话,就可以全面启用mutt咯。

Source: http://www.fwolf.com/blog/post/257

25/11/2006

The Ringer / 圈套 / 扮猪吃老虎

健康的身体是一切好事情的开端,但是在这个世界上,有一些人虽然拥有健康强壮的身体,大脑却有残疾,学名大概称之为"智障",损一点的俗话就是叫"傻子",他们其实生活在另外一个世界中。

和很多电影一样,开始部分的装疯扮傻很无聊,不过这都是剧情需要,不然戏怎么演呢。不过智障人士并不"傻",他们只是思维方式和我们不一样而已,所以在美女Lynn都看不出破绽的时候,就已经揭穿了Steve的诡计,多么讽刺啊。同样在比赛中,智障人士也给了Steve很大的压力,作为一个正常人,想超过经过训练的智障人士也并非容易,投入就会有回报,这句话用在这里太合适了。

虽然标榜为喜剧片,但我想只是指他的结果而已,毕竟这么一个美好的故事,谁会期待其他的结局呢?故事的过程倒趋向于伦理片,只是借用了喜剧的手法罢了,因为观众们不愿看到智障人士生活的苦涩一面。在他们的大笑之后,出了Steve的烦恼,还透这一丝无奈,或许他们自己体会不到,那样就幸福多了。不管怎样,每个人都有自己的烦恼要面对,尊重自己,尊重他人,学会以苦为乐,生活就像天上的云,没准儿会变成什么样子的。

下次公司再裁员,记得学学Stavi,也许你的老板会心软的。

片中押1000美金在Steve身上的人,是听他忏悔然后把他赶出教堂的那位神父么?谁看清了?

Source:http://www.fwolf.com/blog/post/256

22/11/2006

[Ubuntu]fetchmail+procmail+mutt+esmtp初窥

以前我讲过自己的email客户端软件选择历程,现在已经很少用客户端了,大部分时间都在gmail中泡。但是由于历史的沉淀,仍然有很多邮件会发送到tom、126等邮箱中,所以我决心再次涉足email客户端,初步选定linux平台下的fetchmail+procmail+mutt+esmtp组合,主要用于一些不支持转发的国内免费邮箱,如果感觉好的话,或许我会把gmail也加进来?

在fetchmail+procmail+mutt+esmtp的组合中,fetchmail负责收信,procmail负责过滤、分拣邮件,mutt是邮件阅读、撰写工具,esmtp负责发送邮件,在ubuntu下,都可以用apt安装,并且文件都不大:fetchmail 6.3.2-2ubuntu2 332k,procmail 3.22-11ubuntu2 140k,libesmtp5 1.0.3-1 51.9k,esmtp 0.5.1-3 35.3k,esmtp-run 0.5.1-3 3.302k,mutt 1.5.11-3ubuntu2.2 908k。

注意安装mutt的时候,它依赖postfix或者mail-transport-agent,所以要先安装esmtp-run,再安装postfix,因为postfix用于个人收发邮件是有点杀鸡用牛刀了。

然后是配置,配置的时候最好倒序进行,先配发信、过滤什么的,要不然先把收信配置好了,后续的过滤处理还没配就不好玩了。

首先创建.esmtprc,包含如下内容:

# smtp服务器地址
identity fwolf@domain1.com
hostname = smtp.domain1.com:25
username = "fwolf"
password = "pass"
default

identity fwolf@domain2.com
hostname = smtp.domain2.com:25
username = "fwolf"
password = "pass"

# 设置邮件发送代理程序
mda = "/usr/bin/procmail -d %T"

有多个smtp帐号时可以用identity区分。

然后配置mutt,ubuntu中系统的muttrc文件为/etc/Muttrc,可以另存一份为~/.muttrc然后修改,不过里面的默认设置很多都不用动,所以新建一份空的.muttrc然后把个人设置写进来也不错:

# 使用esmtp发信
set sendmail = "/usr/bin/esmtp -v -X ~/log/esmtplog"

有了这一行简单的配置,就可以告诉mutt把新建转交给esmtp进行发送了。现在启动mutt,就能够发信了,试一试吧,过完瘾之后,再来点复杂一些的muttrc配置:

#——–Basic
set beep=yes # beep when an error occurs
unset confirmappend # no confirm when appending message to existed mbox
set copy=yes # whether or not save your outgoing messages for later references
set delete=yes # purge deleted messages without asking
set editor=vim
set fast_reply=yes # donot prompt for to and subject when reply
set folder=~/mail # where to keep my mailboxes
set include=yes # include origin message when reply
set markers=yes # display + before wrapped lines
set mbox="=inbox"
set mbox_type=Maildir # use Maildir storage for mails
unset menu_scroll
set pager_context=1 # display N rows of last list page
set pager_index_lines=6 # mini index rows in list page
set pgp_verify_sig=no # ??
set postponed="=postponed"
set record="=sent" # turns on recording sent message to outgoing
set save_empty=yes # keep mailbox when last message is removed
set sendmail_wait=0 # wait when send mail process run
set status_on_top=no # move status bar to top of screen
set to_chars=" +TCFL"

#——–Folder
# Define the directory where mutt looks for mailboxes to report new mail
mailboxes `echo ~/mail/*`

#——–Format
#set date_format="!%H:%M %a %d %b   "
#set folder_format="%2C %t %8s %d %N %f"
#set index_format="%4C %Z %[%b%d] %-15.15F %s"
#set pager_format="%-10.10i %[!%a %b %d %R]"
#set status_format=" %r %b %f %n   Del %d   Msgs %m %l %> (%P)"

#——–Sort
set sort=threads # sorting the mails in threads
set sort_aux=date-sent # sort brother mails inside threads

#——–Headers
#ignore X-Mozilla-Status X-Mozilla-Status2 X-Accept-Language Delivered-To X-UIDL X-MSMail-Priority X-MimeOLE In-Reply-To
# 显示邮件时,除去默认邮件头列表中的域
# 忽略所有域然后反选您想看到的
ignore *
unignore Date To From: Subject X-Mailer Organization User-Agent
hdr_order Date From To Subject X-Mailer User-Agent Organization

#set alias_file=~/.mail_aliases # Let mutt know save path to aliases.(useless, default value is .muttrc)
#source ~/.mail_alias # load user aliases

#——–Misc
# 使用esmtp发信
set sendmail = "/usr/bin/esmtp -v -X ~/log/esmtplog"

#使用 G 键运行 fetchmail
macro index G "!fetchmail -a -m 'procmail -d %T'\r"
macro pager G "!fetchmail -a -m 'procmail -d %T'\r"

这些配置也只是一些基本的设置,是我从网上搜到的几个muttrc中汇总而来的,一些复杂的功能没有加上,等熟悉了之后再介绍。

再来配置procmail,编辑~/.procmail文件,我是参照这里进行的设置,也是打算熟悉了以后再深入研究:

MAILDIR=$HOME/mail/ #您最好确认该目录存在
LOGFILE=$HOME/log/procmail.log
LOGABSTRACT=no
#VERBOSE=on #…只在调试时使用
VERBOSE=off
FORMAIL=/usr/bin/formail
NL="
"
##处方行以 :0 开始
##不要在处方行加入注解
##使用否条件 ! 禁止一个处方
##条件行以 * 开始,regex 是您的朋友
##条件并列在一起,* 以后的部分都被送到 egrep
##紧接条件的是执行行,在这里是一个邮箱的名称
#使用 formail 捕获复本
:0 Whc: .msgid.lock
| $FORMAIL -D 16384 .msgid.cache

:0 a
$MAILDIR/duplicates/

#我们总是允许邮件来自
:0
* ^From:.*(fwolf\@domain.com)
$MAILDIR/myself/

#接着冲走一些垃圾
:0
* ^Subject:.*(credit|cash|money|debt|sex|sale|loan)
$MAILDIR/spam/

#不要 html 消息
#:0
#* ^Content-Type:.*html
#$MAILDIR/junk/

#将我的邮件列表转到相应邮箱
:0
* ^List-Id:.*gentoo-user
$MAILDIR/gentoo-user/
:0
* ^List-Id:.*gentoo-dev
$MAILDIR/gentoo-dev/
:0
* ^List-Id:.*gentoo-announce
$MAILDIR/gentoo-announce/

#捕获任何其它的 gentoo 邮件
:0
* ^From:.*gentoo.org
$MAILDIR/gentoo/
:0
* ^From:.*@freshmeat\.net
$MAILDIR/freshmeat/

################################
# 最后一条规则:将到达 #
# 这的邮件送到默认邮箱 #
################################
:0
* .*
$MAILDIR/inbox/

# 文件结束

注意每个邮箱目录名的后面都有斜杠"/",这是告诉procmail创建Maildir格式的邮箱目录,和muttrc中设置的一样,都使用Maildir格式存储邮件。

最后配置fetchmail,编辑~/.fetchmailrc文件,我也是参照Sucha's Homesite简单配置了一个,仍然是等熟悉了再详细介绍:

defaults
mda "/usr/bin/esmtp -f %F %T"

# set daemon fetch per 1.5 min
#set daemon 90

poll pop.126.com
proto pop3
uidl
username uname-126
password pass-126
is fwolf
keep

poll pop3.sina.com.cn
proto pop3
uidl
username uname-sina
password pass-sina
is fwolf

最后不要忘记更改配置文件的权限,里面可有你的密码哦。

chmod 600 .esmtprc
chmod 600 .fetchmailrc

现在,在shell中执行

fetchmail -akv -m "/usr/bin/procmail -d %T"

就能看到fetchmail和procmail愉快的收信与分拣了,再进入mutt,就可以对邮件进行管理了,我们的安装到此基本结束。

其实除了esmtp以外,fetcmail、procmail尤其是mutt的配置都非常丰富,我刚开始使用也是比照前人的葫芦画自己的瓢,网上也有很多类似的资源可以搜索到。

现在真的开始担忧mutt用爽了以后,在线的gmail如何处理了,毕竟mutt把邮件都收到了本地进行存储、处理,和gmail在线处理相比,虽然有速度的优势,却又少了可以随时随地使用的特点,我应该如何取舍呢?

Source: http://www.fwolf.com/blog/post/255

21/11/2006

googlegroups悄悄的升级,forward和filter规则的顺序变了

突然在主邮箱中见到了我用其他邮箱(称之为副邮箱吧)给一个groups发的邮件,顿感奇怪,虽然主邮箱是groups的owner,但订阅方式确实"no email",同时还看到googlegroups好像升级了,同一个groups,语言设定和用户偏好设定都是english语言,却仍然时不时显示汉化了的页面,难道说googlegroups在升级的时候强制把所有邮箱都转发到owner邮箱里面了一份?仔细查看主邮箱收到的邮件信息,发现只是在邮件发送过程的最后出现了forward到主邮箱地址的记录:

X-Gmail-Received: b042f7caed4468601bac5c7c7679626991e183a5
Delivered-To: 主邮箱
Received: by 10.78.168.17 with SMTP id q17cs77154hue;
Mon, 20 Nov 2006 23:18:21 -0800 (PST)
Received: by 10.49.91.9 with SMTP id t9mr623211nfl.1164093500618;
Mon, 20 Nov 2006 23:18:20 -0800 (PST)
X-Forwarded-To: 主邮箱
X-Forwarded-For: 副邮箱 主邮箱
Delivered-To: 副邮箱
Received: by 10.49.31.9 with SMTP id i9cs32065nfj;
Mon, 20 Nov 2006 23:18:05 -0800 (PST)
…..
Return-Path: fwolf.mailer1@gmail.com
To: groups地址, 副邮箱
From: 副邮箱

以上记录中有forward to副邮箱地址的内容,这是因为在往groups发送邮件的时候,也的确给自己发了一份,这样邮件会出现在inbox中,便于管理。那为什么主邮箱地址在收信人中没有,也没有订阅groups邮件,邮件发送的最后怎么又forward到主邮箱了呢?后来再登录副邮箱查看设置,才明白原由。

我的副邮箱设置了"Forwarding and POP",把所有邮件都转发到主邮箱中,以免漏掉重要邮件,同时还设置了filter:

Matches: from:(副邮箱) to:(副邮箱)
Do this: Skip Inbox, Delete it

凡是从副邮箱发出的邮件,经过处理之后,就直接删除了。

今天主邮箱意外收到邮件的事情,应该是因为googlegroups造成的,因为以前filter规则在"Forwarding and POP"之前生效,邮件在应用filter规则时就已经被删除了,"Forwarding and POP"便无信可转。现在作了调整,"Forwarding and POP"首先应用,所以主邮箱就收到了一份邮件的拷贝,然后filter规则再生效,一切照旧。

如果还想达到以前的效果,即能自动把副邮箱收到的其他邮件自动转发到主邮箱,又能够自动处理并删除副邮箱自己发送(同时发给自己一份)的邮件,可以这么作:禁用"Forwarding and POP",现有filter不动,再增加一条新的filter规则:

Matches: from:(-副邮箱)
Do this: Forward to 主邮箱

凡不是副邮箱自己发的邮件,再转发到主邮箱中。注意match那一行括号中有一个减号"-",在规则中是排除的意思。

Source:http://www.fwolf.com/blog/post/254

16/11/2006

让你的vim能够查看函数列表

图形界面下的很多编辑软件都可以列出当前编辑文件中的函数列表,以便在编辑的时候能够快速的跳转。vim虽然没有直接提供这种功能,但配合适当的工具和设定,可以完美的实现!

首先还是安装,vim不用装了,ubuntu中自带,用到的ctags需要自己安装一下,不要用旧的那个ctags,新的叫Exuberant Ctags,apt安装即可:apt-get install exuberant-ctags。

然后按照vim.org上的安装说明,下载taglist_42.zip,解压到home目录下的.vim子目录中:

~/.vim$ unzip /home/fwolf/taglist_42.zip
Archive: /home/fwolf/taglist_42.zip
inflating: plugin/taglist.vim
inflating: doc/taglist.txt

进入$HOME/.vim/doc目录,打开目录,运行".helptags ."命令,注意后面的点不要拉了,这是为了生成ctags帮助文件的索引,然后才能正常使用帮助。(原来vi帮助中的ctrl+]进入链接、ctrl+T返回也是这么来的)

现在,再启动vim,tags功能就可以用了:
vim中使用ctags的效果截图

大概用法:
在使用vim的时候,使用:TlistToggle命令切换函数列表的开、关。
按住ctrl键然后按两下w键在正常编辑区域和tags区域中切换。
在tags区域中,把光标移动到变量、函数名称上,然后敲回车,就会自动在正常编辑区域中定位到指定内容了,很方便的。

常用的几项.vimrc设置:

"禁止自动改变当前Vim窗口的大小
let Tlist_Inc_Winwidth=0
"把方法列表放在屏幕的右侧
let Tlist_Use_Right_Window=1
"让当前不被编辑的文件的方法列表自动折叠起来, 这样可以节约一些屏幕空间
let Tlist_File_Fold_Auto_Close=1

参考 滇狐的说明

Source:http://www.fwolf.com/blog/post/253

14/11/2006

倒腾硬盘上的资料

我用的电脑上本来有两块硬盘,一块大一点儿的为主盘,/ /boot /usr /var全挂在上面,剩余的空间分成/big1 /big2等大分区存储数据,另外一块小一点的为副盘,主要挂/home,小一点的这块盘是从以前安装ubuntu的电脑的主盘,电脑升级以后,直接调整了一下就挂在/home下用了。

但是最近同事们嫌我这快小一点的硬盘噪音太大了,吵得慌,于是另外找了一块旧硬盘,发现还是有声音,接着再找一块稍微新一点的盘,这回没声音了,但这块硬盘在也用着呢,换下来的话还要找块硬盘顶上,于是,硬盘及需要倒腾的内容如下:
硬盘A 现用主盘,挂着/ /boot /usr /var等,不动
硬盘B 现用副盘,挂着/home,准备撤下,但数据要保留
硬盘C 噪音小一点的旧硬盘,准备用来装硬盘D上的原有数据。
硬盘D 没有噪音的旧硬盘,准备用来更换硬盘B,原有数据备份到硬盘C中。
调整之前电脑1上安装ubuntu系统,挂硬盘A、B,电脑2上安装windows,挂硬盘D;
调整之后电脑1上安装ubuntu系统,挂硬盘A、D,电脑2上安装windows,挂硬盘C。
有点乱,所以要先交代清楚,分区格式之间的不同就不说了,说出来更乱。

首先把硬盘D的东西倒到硬盘C中,直接把硬盘C挂在主机2上,识别出来之后分区,然后把硬盘D上除C:盘之外的内容都拷贝上,C:盘的内容无法直接复制,下载一个ghost,然后用外置光驱启动,运行ghost,采用分区对分区的复制方式把c:盘的内容复制到了硬盘C上。

至此,主机2上的工作基本做完,把硬盘D拆下,把硬盘C换上应该就能够启动原来的系统了。但是由于在ghost的时候需要进cmos修改启动顺序,却又不知道cmos密码,于是——放电,一放电电脑日期成了2000年,ghost之后启动windows xp就卡死在登录屏幕了,无奈只得重装。虽然是自己忘记了修改cmos时间导致的,但winxp的这点限制实在不爽,用户要为反盗版付出多大代价?还不是羊毛出在羊身上?

接下来要在主机1上把硬盘B的内容倒到硬盘D中,但主机2是dell的品牌机,自带硬盘为sata接口,而硬盘B、D都是普通ide接口,只有一条ide连接线,两块硬盘就都连在这一条线上。启动主机1上原来的系统,发现在检查光驱文件分区的时候卡住不动了,原来在fstab中hda还是光驱,现在换成硬盘了,所以启动的时候报错。关机-摘下硬盘D-启动-更改fstab-关机-安上硬盘D,这才好,然后对硬盘D重新分区、拷贝数据。

数据转换完成之后,摘掉硬盘B——可以退伍了,装上硬盘D,fstab按照新的分区划分进行更新,然后重启系统。本来以为一切都没事了,谁知居然提示没有可引导的分区!这会是什么原因呢?硬盘A是在安装ubuntu时进行分区的,/boot也在上面,硬盘D原来是dos的可引导分区,现在删掉换成ext3分区了,难道我摘下的硬盘B反而是引导分区,就因为上一次安装ubuntu时已经设定好了?不管什么原因,现在当务之急是光盘启动,安装grub。在这一点上ubuntu的livecd光盘反倒不太好用,启动过程太漫长了,grub安装参见 恢复 Ubuntu 6.06 的 grub 菜单,命令大概为:

mkdir fakeroot
mount /dev/sda2 fakeroot
ls -l /dev/sda
chroot fakeroot
mount /dev/sda1 /boot
mount /dev/sda3 /usr
mknod /dev/sda b 8 0
grub-install /dev/sda

由于原先grub的menu.lst什么的都在,所以安装比较顺利,grub提示有两块硬盘0,0为hdb硬盘D,1,0为sda硬盘A。重启,顺利见到了grub的启动菜单,选择后居然又无法启动,提示文件找不到?能够看到菜单说明grub安装是正常的,文件找不到说明linux内核文件的位置配置不对,经过反复尝试,发现把root(1,0)更改为root(0,0)就能够正常启动了,这个和grub提示的硬盘情况略有不同,原因我也不知道。启动之后修改menu.lst中, 把(1,0)全部替换为(0,0),以后启动就完全正常了,看来sata、ide硬盘共存的情况下,先后顺序有可能会变化。

工作基本上都完成了,唯一的遗憾是在备份原先挂/home的硬盘B的数据时,只是用了个cp * -rv,所有的隐藏文件,就是以点.开头的文件都没有拷贝过来,导致所有的设置全部丢失。耗时一天,总结一下,有几点需要注意:

  • cmos放电之后,记得立刻更改cmos日期,否则会导致winxp无法启动(只能重装解决?),linux应该不存在这个问题。
  • 原先挂载光驱的地方如果要换成硬盘,提前把fstab中的光驱挂载项删除,不然启动时会在检查文件系统时卡壳。
  • grub安装不难,首先保证grub安装上,然后有问题再调整linux内核镜像的地址,在sata和ide硬盘共存的情况下注意排列顺序。
  • cp *是不会拷贝dot开头的隐藏文件的,有可能的话,还是cp 上一级目录比较保险,或者补上一个cp .*。
  • 不是用useradd -m创建的用户home目录,里面没有.bash_profile文件,会导致ssh登录到这个主机时.bashrc不起作用,解决方法为复制过来一个即可。

Source:http://www.fwolf.com/blog/post/222

07/11/2006

生成影片的预览图像另Mencoder和ffmpeg使用实例小全

下载电影的时候,我们总希望在全部下载完成之前能够预览一下影片内容,于是发布者时常会放一些影片截图在种子文件中,或者直接贴到网上,也有一些截图是一张图片,但包含很多幅影片在一起,就像下面这张:

imagemagick-montage-sample

有很多软件能够截取影片图像、合并图像,但如果影片太多,比如视频网站为用户上传的图像生成预览图之类的,人工在gui方式下操作就不可取了,我们需要在命令行方式下来截取、合并。

首先,截取影片图像使用最多的就是mplayer或者ffmpeg,我用mplayer比较熟,本文就以此为例了,ffmpeg功能也是非常强大的,但据说支持的文件格式却不丰富。mplayer截取影片图像的基本命令为:

mplayer -ss START_TIME -noframedrop -nosound -vo jpeg -frames N NAME_OF_VIDEO_FILE

上例中,-ss指定开始的时间,结合-frames参数,限定从某个时间开始、截取几帧图像。为了体现整个影片的内容,我需要在影片中间隔时间相同的几个点、每个点截取1帧图像,所以按道理应该用-frames 1,但是mplayer这样截图的情况下,第一帧似乎永远都会截取到一个黑屏,所以我常用-frames 2。截取下来的图像保存在了当前目录,名称从00000001.jpg开始依次递增,按照-frames 2,就是取00000002.jpg为结果, 删除00000001.jpg即可。经过简单实验,在截取wmv、rmvb影片时,前面的好几帧都会是黑屏,也只能参考上面的做法多取几帧了。

为了取影片中间隔大致相同的几个点,可以用-ss指定时间,也可以用-sb指定开始字节,在我的实际使用中,使用-sb只会得到黑屏,所以通过文件大小来设置间隔点的办法不行,只能用-ss时间间隔了,这就需要首先得到影片的总时间。好在mplayer为我们提供了类似的功能:

mplayer -identify movie-filename -nosound -vc dummy -vo null

这样会输出一大堆影片信息,从中截取所需内容即可,在bash shell中,取得影片总时间长度(以秒为单位)的命令如下:

FILESIZE=`mplayer -identify -nosound -vc dummy -vo null $1 | grep ID_LENGTH | sed -r 's/ID_LENGTH=([[:digit:]]*)(\.[[:digit:]]*)?/\1/g'`

有了影片的总时长,我们就可以根据所要截取的帧数,计算出每个间隔点的时间位移了。不过要注意一般影片的开始-ss 0和结束-ss TOTAL_TIME_OF_VIDEO截取下来都会是黑屏,在处理的时候要分别加上和减去若干秒。

截取工作完成后,我们拥有了一堆000000xx.jpg文件,如果能把这些文件都放到一个文件中,每行2张,成为一张大图片,在发布的时候会很方便。所以,我们使用imagemagick中的montage命令来实现:

montage -geometry +0+0 -tile 2 *.jpg montage.jpg

-geometry +0+0是设定使用原始图片大小,-tile 2参数设定每行放2张图片,最后一个参数是要生成的目标文件名,现在,我们就能够得到像刚才那张一样的图片了。

原理已经讲清楚了,可以自己写一个bash脚本来方便调用,我在网上找到了一个很不错的例子,可以在这个基础上进行修改,过程不再详述了。

下面再列一些在网上找到的其他mplayer、mencoder、ffmpeg的使用实例:

mplayer获取影片信息
mplayer -identify movie-filename -nosound -vc dummy -vo null
从所有输出中可以grep到如下信息:
- filetype: ASF file format detected.
- dimensions and format: VIDEO: [MP43] 320×240 24bpp 1000.000 fps 0.0 kbps ( 0.0 kbyte/s)
- video format: ID_VIDEO_FORMAT=MP43
- width (dimensions): ID_VIDEO_WIDTH=320
- height (dimensions): ID_VIDEO_HEIGHT=240
- length in seconds: ID_LENGTH=98.00
参考8

mencoder图片做成电影
#用当前目录中的所有JPEG文件创建DivX4文件:
mencoder \*.jpg -mf on:w=800:h=600:fps=25 -ovc divx4 -o output.avi
#用当前目录中的一些JPEG文件创建DivX4文件:
mencoder -mf on:w=800:h=600:fps=25 -ovc divx4 -o output.avi \*.jpg
#用当前目录中的所有JPEG文件创建Motion JPEG(MJPEG)文件:
mencoder -mf on:w=800:h=600:fps=25 -ovc copy -o output.avi \*.jpg
#用当前目录中的所有PNG文件创建一个非压缩的文件:
mencoder -mf on:w=800:h=600:fps=25:type=png -ovc rawrgb -o output.avi \*.png
简单用法:
mencoder *.jpg -mf on:fps=15 -o output.avi -ovc xvid
参考6 参考7

ffmpeg屏幕录像
ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s 1024×768 ~/test.avi
  其中,-vd x11:0,0 指录制所使用的偏移为 x=0 和 y=0,-s 1024×768 指录制视频的大小为 1024×768。录制的视频文件为 test.avi,将保存到用户主目录中。其他选项可查阅其说明文档。
  如果你只想录制一个应用程序窗口或者桌面上的一个固定区域,那么可以指定偏移位置和区域大小。使用xwininfo -frame命令可以完成查找上述参数。
  你也可以重新调整视频尺寸大小,如:./ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -i ~/test.avi -s 800×600 ~/test-800-600.avi。
参考5

mplayer对video进行截屏 截图(wmv mpeg mov flv all works)
mplayer 78.mov -ss 1 -nosound -vo jpeg:outdir=./ -frames 2
我截的第一张图不知为何全部都是黑屏
参考4

转换为flv文件
mencoder NOW.wmv -ffourcc FLV1 -of lavf -ovc lavc -lavcopts vcodec=flv:acodec=mp3:abitrate=56 -srate 22050 -oac mp3lame -o NOW.flv
ffmpeg -i a.asf -ab 56 -ar 22050 -b 500 -r 15 -s 320×240 asf.flv
参考3

使用ffmpeg抓图
ffmpeg -i test2.asf -y -f image2 -ss 08.010 -t 0.001 -s 352×240 b.jpg
jpg: ffmpeg -i test.asf -y -f image2 -t 0.001 -s 352×240 -ss a.jpg //注意-ss就是要提取视频文件中指定时间的图像
jpg: ffmpeg -i asf.flv -y -f image2 -t 1 asf.jpg
gif: ffmpeg -i test.asf -vframes 30 -y -f gif a.gif
参考3 参考2

如何合并几个视频片段
mencoder -oac copy -ovc copy -idx -o output.avi video1.avi video2.avi video3.avi
* 其中,-oac copy 选项告诉 mencoder 要正确拷贝音频流。而 -ovc copy 选项则是拷贝视频流。
* 如果在视频文件中没有找到索引的话,那么 -idx 选项会要求 mencoder 建立它。
* -o 选项指定输出文件的名称。
* 最后几个参数为需要合并的几个视频片段。
参考1

Source:http://www.fwolf.com/blog/post/251

自己写js代替手工点击

有一些变态网页,会有一大堆radio或者checkbox让用户去点,或者有很多+要逐个展开,如果经常使用这样的功能,手工一个个的去点是很笨的做法,如果结合我原来介绍过的用js丰富你的书签功能 ,自己写点javascript就方便多啦。

例如,网页上有几百个+需要展开,而+部分的html代码如下:

其中onclick动作调用的uf_Expand就是实现展开的函数,于是,我们可以遍历所有的img对象,利用src="collapse.gif"来辨别这是一个点击展开的"+"(如果能配合id来使用当然更好啦),然后调用它的onclick动作:

javascript:
void(
(
function()
{
var img=document.getElementsByTagName("img");
var length=img.length;
for (var i=0;i {
obj=img[i];
if ("http://www.fwolf.com/collapse.gif"==obj.src)
{
obj.onclick();
}
}
}
)
()
);

注意img的src属性和html中看到的并不完全一样,加上了前面的域名部分,这是浏览器在解析html的时候自动加上的。现在只需我们轻轻点一下做好的书签按钮,就可以展开所有的+了。

还有一种情况,那就是两次展开之间需要一定的时间间隔,毕竟谁的服务器也无法承受一下子多出几百次请求,一般这种情况的解决都是写两个函数,一个为启动函数,使用setTimeout方法启动另外一个主体函数,主体函数在作完一次处理之后,再使用setTimeout调用自身。由于我们这里需要作的处理比较简单,所以也可以采取直接setTimeout,通过增加timeout时间的方式来实现。只需把上例代码中的"obj.onclick();"这一行更改为:

setTimeout("document.getElementsByTagName('img')[" + i + "].onclick()", 3000*i);

就可以实现每隔3秒自动展开下一个"+"了。

Source:http://www.fwolf.com/blog/post/252