新手问题 请教标准库中 DBM 的用法

gotnix · 2014年01月06日 · 最后由 gotnix 回复于 2014年01月07日 · 2542 次阅读

大家好!

Ruby 新手,之前只写过 Bash 脚本;第一次发帖,请多多指教!

我用 Berkeley DB 保存 Vsftpd 的用户名和密码,文件如下:

bash> $ cat > test.txt << EOF
>foo
>Hello
>bar
>World
>EOF

bash> $ db48_load -T -t hash -f ./test.txt ./test.db

bash> $ file test.db
test.db: Berkeley DB (Hash, version 9, native byte-order)

bash> $ db48_dump -p test.db
VERSION=3
format=print
type=hash
h_nelem=2
db_pagesize=4096
HEADER=END
 foo
 Hello
 bar
 World
DATA=END

如果用 shell 写添加用户的脚本,就要先修改文本文件,然后 db_load 成为 BDB 文件。要保证私自篡改过的文本文件不会生效,还要先把 BDB 文件 db_dump 成文本,追加新用户和密码,然后删除 BDB 文件,再 db_load。步骤很繁琐,时间久了也不好维护,就想用 Ruby 写个脚本试试。

代码如下:

2.0.0-p353 :001 > require 'dbm'
 => true 
2.0.0-p353 :002 > DBM.open('./test') do |bdb|
2.0.0-p353 :003 >     bdb.each_pair {|key, value| print "#{key}: #{value}\n"}
2.0.0-p353 :004?>   end
foo: Hello
bar: World
 => #<DBM:0x00000000e62940> 
2.0.0-p353 :005 >

刚开始用 DBM 不支持 Berkeley DB 的文件格式,使用DBM.open()会创建 test.dir 和 test.pag 这 2 个 GNU dbm 格式的数据文件;然后安装了 libdb-4_8-devel-4.8.30-25.2.1.x86_64 这个包,RVM 重新安装了 Ruby 就可以了。

我想请教一下: 1、如果 Berkeley DB 和 GNU dbm 的开发库都装了,如何在打开或者创建文件的时候使用指定的格式? 文档 中说是自动的:

Any file extensions needed will be supplied automatically by the dbm library. For example, Berkeley DB appends '.db', and GNU gdbm uses two physical files with extensions '.dir' and '.pag'.

2、这次解决问题安装 BDB 的开发库是靠猜的,Ruby 有没有类似 PHP 中phpinfo()之类的,可以查看支持哪些扩展,这样应该很快就会找到不支持 BDB 文件的原因?

应该是编译 Ruby 时就决定好是用 berkleydb 或者 gnu dbm 了,看 DBM::VERSION 可以知道是哪种。如果系统两种都有,可以在安装时加 --with-dbm-type 指定,参见 ruby 源码目录/ext/dbm/extconf.rb

#1 楼 @luikore DBM 应该是在编译 Ruby 的时候决定的,现在是:

2.0.0p353 :001 > require 'dbm'
 => true 
2.0.0p353 :002 > p DBM::VERSION
"Berkeley DB 4.8.30: (October 21, 2013)"
 => "Berkeley DB 4.8.30: (October 21, 2013)" 
2.0.0p353 :003 > 

现在应该可以用GDBM来操作 GNU dbm 的文件。

多谢指点!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号