2009年4月16日星期四

parrot 鹦鹉 1.0 release

鹦鹉,对于 perl 6 意义重大
相当于真正执行二进制代码的虚拟机
如今,鹦鹉已经 release 了
但是很讽刺地,它现在的发展似乎明显超越了 perl 6 的开发进展

不管怎么说,它的正式发布,还是要恭喜的

2009年4月14日星期二

perl 参数的 I 和 i

perl 参数的 i 和 I 都可以指定路径
其中 I 指定的是文件夹
i 指定的是 pm 文件

比如 /Test 文件夹下有 Teacher.pl 和 Boy.pm 两个文件

../
./
|-Test/
  |-Boy.pm
  |-Teacher.pl

其中 Teacher.pl 调用 Boy.pm 代码
代码如下:


#!/cygdrive/c/Perl/bin/perl 

package Test::Teacher;
use strict;
use warnings;

use Test::Boy;

my @eth = Test::Boy::getEverything();

foreach(@eth){
print "out: ".$_."\n";
}
#!/cygdrive/c/Perl/bin/perl 
package Test::Boy;
use strict;
use warnings;

my @everything = 1 .. 9;

sub getEverything{
@everything;
}
1 假设当前路径为 /cygdrive/e/pl可以使用
perl Test/Teacher.pl
注:perl 会从 ./ 下寻找 Test::Boy.pm,也就是相当于 -iTest::Boy 参数

2 假设当前路径为 /cygdrive/e/pl/Test 时
则需要使用
perl -I../ Teacher.pl
注:perl 会从 ../ 寻找 Test::Boy.pm
use Foo::Bar 意味着什么
   ——摘自 http://wiki.perlchina.org/Simple_module_tutorial

use Foo::Bar
并不意味着在 @INC 的目录中寻找一个叫做Foo::Bar.pm的模块文件。
它的意思是在@INC的目录中寻找一个叫做‘Foo’的“子目录”,
然后在其中找一个叫做“Bar.pm”的“模块”。
现在,如果我们成功"use"了一个模块,
那么我们就可以通过完整的包路径语法
&PACKAGE::FUNCTION
使用这个模块中的所有函数。
当我们说&Foo::Bar::some_func的时候,
我们指的是“包的名字”而不是那个在use中曾使用的包含路径的文件名。
这会允许你可以在一个use过的文件中包含很多包名字。
实际使用中这些名字通常是相同的。


另外,假设 Teacher.pl 在 Test 文件夹同级

../
./
|test/
| |-Boy.pm
|-Teacher.pl

如果要调用 Boy.pm,也要在 Boy.pm 开头的 package 生命中写清
Test::Boy
即:pm 一定要放在 pm 内与包路径相同的文件夹下,并在文件夹外层调用

vim 7.0 也有 tab 页

古人云:vi 是个好东西

vi 的 buffer 是个不太好看的东西——中文真是博大精深,我主要表达的是不容易看清楚的意思
:ls 是个很好用的命令,但不够直观
用户一定要 ls 一下才能看清楚 buffer 里的东西
这样的操作显然违背了 vi 的特色——让人体任何部位的移动尽量减少,哪怕一毫米

于是,vim 7.0 开始支持 tab(标签页)
gvim 下的 tab 更是直观
最简单常用的用法如下:

netrw 中
t 把光标指向的文件在新标签页中打开
通常模式下
:tabnew 打开一个新的标签页
:tabc[lose] 关闭当前的标签页
:tab help 在一个新标签页中打开帮助
:help :tab 在帮助中打开关于标签页内容
:tab help :tab 在新标签页中打开关于新标签页的帮助

其他的,按以上方法查帮助吧

2009年4月13日星期一

perl socket

一个服务端

#!/cygdrive/c/Perl/bin/perl -w

use strict;
use warnings;

use IO::Socket;
use Tk;

sub sendf{
my $socket=IO::Socket::INET->;new(
       PeerHost      => 'localhost',
       Protor        => "tcp",
       PeerPort      => 3067
       );
die "no socket $@ \n" until $socket;
print "client created \n";

print $socket "client say: ".shift."\n";
$socket->;flush();
close($socket);
}

my $mw = MainWindow->;new;
$mw->;Button(    -text=>"say hello",    -command=>sub{sendf("Hello, server!");}    )->pack;

MainLoop;
一个客户端(只有一个按钮,按一下,就去跟服务器发消息)

#!/cygdrive/c/Perl/bin/perl 

use strict;
use warnings;

use Tk;
use IO::Socket;

my $socket = IO::Socket::INET->;new(
LocalHost      => 'localhost',
Proto          => "tcp",
LocalPort      => 3067,
Listen         => 5
) or die 'no socket $@ \n';
print "server created \n";

while(my $nsocket = $socket->;accept()){
while(defined (my $buf = <$nsocket>;))
{
   print "\n$buf";
}

}

close($socket);
print "server finished\n";
注意
服务器端 socket 创建时,listen 参数一定要设定,否则不会报错,但服务器不会被 accept() 阻塞

2009年4月11日星期六

sudo

sudo 功能不赘述,修改权限时,用 visudo 很安全——校验文件配置是否正确,如果不正确,在保存退出时就会提示你配置出错位置。
但我还是喜欢真正的vim。修改执行权限可以通过 vim:
vim /etc/sudoers

编辑中,支持别名(alias,跟变量差不多含义)

Alias主要分成4种
Host_Alias
Cmnd_Alias
User_Alias
Runas_Alias

1) 配置Host_Alias:就是主机的列表
Host_Alias HOST_FLAG = hostname1, hostname2, hostname3
2) 配置Cmnd_Alias:就是允许执行的命令的列表
Cmnd_Alias COMMAND_FLAG = command1, command2, command3
3) 配置User_Alias:就是具有sudo权限的用户的列表
User_Alias USER_FLAG = user1, user2, user3
4) 配置Runas_Alias:就是用户以什么身份执行(例如root,或者oracle)的列表
Runas_Alias RUNAS_FLAG = operator1, operator2, operator3
5) 实际上最终目标是要拼成如下格式
配置权限的格式如下:
USER_FLAG HOST_FLAG=(RUNAS_FLAG) COMMAND_FLAG
如果不需要密码验证的话,则按照这样的格式来配置
USER_FLAG HOST_FLAG=(RUNAS_FLAG) NOPASSWD: COMMAND_FLAG

配置示例:
# sudoers file.
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the sudoers man page for the details on how to write a sudoers file.
#

# Host alias specification
Host_Alias EPG = 192.168.1.1, 192.168.1.2

# User alias specification

# Cmnd alias specification
Cmnd_Alias SQUID = /sbin/shutdown, /bin/rm

# Defaults specification

# User privilege specification
root ALL=(ALL) ALL
support EPG=(ALL) NOPASSWD: SQUID

# Uncomment to allow people in group wheel to run all commands
# %wheel ALL=(ALL) ALL

# Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL

# Samples
# %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users localhost=/sbin/shutdown -h now

注意
涉及到路径时最好写绝对路径
每行中间的空格,可以是 tab
保存后不需要重启,或者被修改帐户重新登录之类。直接使用就行

2009年3月31日星期二

openfire is very easy to use


本地试验,运行了个 xmpp 聊天服务器,很简单,很好用
openfire 作为服务器端,非常简单
中文控制台界面,足够了

2009年3月27日星期五

Debian 5 lost eth0

我弄丢了我虚拟机上的的 eth0!

最近我做得最大的动作,就是把我的 Debian 4 升级到 Debian5
——其实那已经是很久以前的事情了,但当时可能用的是 apt-get upgrade,所以不知不觉就升级上来了
当我突然发现版本号变化的时候,赶快去看了看这个最大版本号的升级带来了什么

我感兴趣的大概只有两件事
1. apt-get 系列改为 aptitude——仅凭这一点,就足以升级一个大版本号了
2. log 系统改为 rsyslog——其实这影响也不大,直接用 aptitude install 一下新的,就可以自动删除两个旧的 log 服务器了

以上更新完之后,重启
然后……我发现不能连接网络啦!!

ifconfig 的结果是只有 lo,没有eth0
这是一个很奇怪的现象,而这个现象显然不是来自系统升级——因为早就升级过了
刚做过的动作只是安装了 aptitude 和改变了 log 服务
但是这与网络没什么关系

上网查询了一下处理方法,有人说执行以下 dhconfig 就可以解决
试了一下,可行
但是重启之后还是要再次执行

很不甘心地检查了一下启动日志,发现出现了一个很诡异的 eth1
并且在 dhconfig 的时候,似乎也是通过配置 eth1 来使用网络的

目前问题原因仍在查询中,但更加合理的临时处理方案是,把
/etc/network/interfaces
文件里的 eth0 改成 eth1

这个方法对于有既存脚本针对 eth0 的人,显然不好用的
不过我可以暂时应付一下

另:
grep /var/log/kern.log
看到许多 udev: renamed network interface eth0 to eth1

2009年3月9日星期一

发现 Groovy

很眼馋 C++ 有 lua
我一直在寻找 Java 的脚本语言
最近发现 Groovy,也发现我不知道的脚本语言的用法——闭包

2009年2月5日星期四

perl cheatsheet(from perldoc)


下面是个关于 Perl 的 CheatSheet,也就是那种什么也没学的时候就先背下来,以后越学越受用的关键内容
格式……很讨厌,是从 perldoc 搞来的
blogger 的 css 让我搞了半天啊
绝对不做美工,果然要遭报应的……

CONTEXTS SIGILS ARRAYS HASHES
void $scalar whole: @array %hash
scalar @array slice: @array[0, 2] @hash{'a', 'b'}
list %hash element: $array[0] $hash{'a'}
&sub
*glob SCALAR VALUES
number, string, reference, glob, undef
REFERENCES
\ references $$foo[1] aka $foo->[1]
$@%&* dereference $$foo{bar} aka $foo->{bar}
[] anon. arrayref ${$$foo[1]}[2] aka $foo->[1]->[2]
{} anon. hashref ${$$foo[1]}[2] aka $foo->[1][2]
\() list of refs
NUMBERS vs STRINGS LINKS
OPERATOR PRECEDENCE = = perl.plover.com
-> + . search.cpan.org
++ -- == != eq ne cpan.org
** < > <= >= lt gt le ge pm.org
! ~ \ u+ u- <=> cmp tpj.com
=~ !~ perldoc.com
* / % x SYNTAX
+ - . for (LIST) { }, for (a;b;c) { }
<< >> while ( ) { }, until ( ) { }
named uops if ( ) { } elsif ( ) { } else { }
< > <= >= lt gt le ge unless ( ) { } elsif ( ) { } else { }
== != <=> eq ne cmp for equals foreach (ALWAYS)
&
| ^ REGEX METACHARS REGEX MODIFIERS
&& ^ string begin /i case insens.
|| $ str. end (before \n) /m line based ^$
.. ... + one or more /s . includes \n
?: * zero or more /x ign. wh.space
= += -= *= etc. ? zero or one /g global
, => {3,7} repeat in range /o cmpl pat. once
list ops () capture
not (?:) no capture REGEX CHARCLASSES
and [] character class . == [^\n]
or xor | alternation \s == whitespace
\b word boundary \w == word characters
\z string end \d == digits
DO \S, \W and \D negate
use strict; DON'T
use warnings; "$foo" LINKS
my $var; $$variable_name perl.com
open() or die $!; `$userinput` use.perl.org
use Modules; /$userinput/ perl.apache.org
  FUNCTION RETURN LISTS
stat localtime caller SPECIAL VARIABLES
0 dev 0 second 0 package $_ default variable
1 ino 1 minute 1 filename $0 program name
2 mode 2 hour 2 line $/ input separator
3 nlink 3 day 3 subroutine $\ output separator
4 uid 4 month-1 4 hasargs $| autoflush
5 gid 5 year-1900 5 wantarray $! sys/libcall error
6 rdev 6 weekday 6 evaltext $@ eval error
7 size 7 yearday 7 is_require $$ process ID
8 atime 8 is_dst 8 hints $. line number
9 mtime 9 bitmask @ARGV command line args
10 ctime just use @INC include paths
11 blksz POSIX:: 3..9 only @_ subroutine args
12 blcks strftime! with EXPR %ENV environment

Perl命令行应用介绍(转)


作 者: Dave Cross
发 表:August 10, 2004
原 名: Perl Command-Line Options
原 文:http://www.perl.com/pub/a/2004/08/09/commandline.html
译 者: "Qiang":qiang

Perl 有很多命令行参数. 通过它, 我们有机会写出更简单的程序. 在这篇文章里我们来了解一些常用的参数.

Safety Net Options

在使用 Perl 尝试一些聪明( 或 stupid) 的想法时, 错误难免会发生. 有经验的 Perl 程序员常常使用三个参数来提前找到错误所在,

-C 是第一个. 这个参数编译 Perl 程序但不会真正运行它. 由此检查所有语法错误. 每次修改 perl 程序之后我都会立刻使用它来找到任何语法错误.
$ perl -c program.pl
-W 是第二个参数. 它会提示你任何潜在的问题. Perl 5.6.0 之后的版本已经用 use warnings; 替换了 -w .你应该使用 use warnings 因为它要比 -w 更灵活.
-T 是第三个参数. 它把 perl 放到了 tain 模式. 在这个模式里, Perl 会质疑任何程序外传来的数据. 例如,从命令行读取, 外部文件里读取 或是 CGI 程序里传来的数据. 这些数据在 -T 模式里都会被 Tainted 掉.
Tainted 数据不可以被用来和外部交互. 例如 使用在 system 调用和用作 open 的文件名. perlsec 文档里有更多什么数据会被Tainted 掉的例子.
要想使用 Tainted 的数据就需要 untaint这个数据. untaint 是通过正则表达式来实现.这里我不会太多的讲述 taint 模式. 如果你要编写的程序 (例如 CGI 程序) 需要从从用户那里接受不可知的输入, 我推荐使有 taint 模式

-d ,Perl Debugger , 在这里值得一提但我们无法顾及, 我推荐阅读文档 'perldoc perldebug' 或 Richard Foley 的 Perl Debugger Pocket Reference 一书.

Command-Line Programs

下面的几个 Perl 参数可以让短小的 Perl 程序运行在命令行. -e 可以让 Perl 程序在命令行上运行.例如, 我们可以在命令行上运行 "Hello World" 程序而不用把它写入文件再运行.
$ perl -e 'print "Hello World\n"'
多个 -e 也可以同时使用, 运行顺序根据它出现的位置.
$ perl -e 'print "Hello ";' -e 'print "World\n"'
象所有的 Perl 程序一样, 只有程序的最后一行不需要以 ; 结尾.
虽然你也可以象通常一样引用模块, 但 -M 让它变得更容易.
  $ perl -MLWP::Simple -e 'print head "http://www.example.com"'
-M模块名 和 use 模块名 一样. 如果不想引入模块的缺省值, 你可以使用 -m. -m模块名 和 use 模块名() 一样. 例如下面这个例子, 因为 head 函数是缺省引入,而使用 -m 时就不会, 结果是没有输出.
  $ perl -mLWP::Simple -e 'print head "http://www.example.com"'
-m 和 -M 通过 = 来引入某个模块的特别函数.
 $ perl -MCGI=:standard -e 'print header'
这里, CGI.pm 的 ":standard" 被引入, header 函数因此可以使用.要引入多个参数可以通过使用引号和逗号.
$ perl -MCGI='header,start_html' -e 'print header, start_html'
这里我们引入了 header 和 start_html 函数.
Implicit Loops
-n 和 -p 增加了循环的功能, 使你可以一行一行来处理文件.
 $ perl -n -e 'some code' file1


这与下面的程序一样.
LINE:
while (<>;) {
# your code goes here
}
<>; 打开命令行里的文件,一行行的读取.每一行缺省保存在 $_
  $ perl -n -e 'print "$. - $_"' file
上面的这一行可以写成
  LINE:
while (<>;) {
print "$. - $_"
}
输出当前行数 $. 和当前行 $_.
-p 可以让上面的程序变得更容易. -p 会输出 $_ 就像这样
LINE:
while (<>;) {
# your code goes here
} continue {
print or die "-p destination: $!\n";
}
continue 在这里保证print 在每次循环都会被调用.
使用 -p, 我们的打印行数程序可以改为
  $ perl -p -e '$_ = "$. - $_"'
注意到那个 LINE: 标签 ? 我们可以利用它来跳到下一个循环. 使用 next LINE
  $ perl -n -e 'next LINE unless /pattern/; print $_'
如果想在循环的前后做些处理, 可以使用 BEGIN 或 END block. 下面的这一行计算文件里的字数.
  $ perl -ne 'END { print $t } @w = /(\w+)/g; $t += @w' file.txt
每一行所有匹配的字放入数组 @w , 然后把 @w 的元素数目递加到 $t. END block 里的 print 最后输出文件总字数.
还有两个参数可以让这个程序变得更简单. -a 打开自动分离 (split) 模式. 空格是缺省的分离号. 输入根据分离号被分离然后放入缺省数组 @F. 由此,我们可以把上面的程序改写为
$ perl -ane 'END {print $x} $x += @F' file.txt
你也可以通过 -F 把缺省的分离号改为你想要的.例如把分离号定为非字符:
$ perl -F'\W' -ane 'END {print $x} $x += @F' file.txt
下面通过 Unix password 文件来介绍一个复杂的例子. Unix password 是文本文件, 每一行是一个用户记录, 由 冒号 : 分离. 第 7 行是用户的登录 shell 路径. 我们可以得出每一个不同 shell 路径被多少个用户使用 :
  $ perl -F':' -ane '$s{$F[6]}++;' \
>; -e 'END { print "$_ : $s{$_}" for keys %s }' /etc/passwd
虽然现在不是一行, 但是你可以看出使用参数可以解决什么问题.
Record Separators
以前我提到过 $/ 和 $\ -- 输入,输出分隔号. $/ 用来分隔从文件句柄里读出的数据, 缺省 $/ 分隔号是 \n , 这样每次 从文件句柄里就会一行行的读取. $\ 缺省是空字符, 用来自动加到要 print 的数据尾端. 这就是为什么很多时候 print 都要在末尾 加上 \n.
$/ 和 $\ 可与 -n -p 一起使用. 在命令行上相对应为 -0 (零) 和 -l ( 这是 L ). -0 后面可以跟一个 16 进制或8进制数值, 这个值用来付给 $/ . -00 打开段落模式, -0777 打开slurp 模式 (即可以一次把整个文件读 入) , 这与把 $/ 设为空字符和 undef 一样效果.
单独使用 -l 有两个效果, 第一自动 chomp 输入分隔号, 第二 把$/ 值付给 $\ ( 这样 print 的时候就会自动在末尾加 \n )
我个人常常使用 -l 参数, 用来给每一个输出加 \n. 例如
$ perl -le 'print "Hello World"'
In-Place Editing
使用已有的参数我们可以写出很有效的命令行程序. 常见的Unix I/O 重定向:
 $ perl -pe 'some code' <>; output.txt
这个程序从 input.txt 读取数据, 然后做一些处理再输出到 output.txt. 你当然也可以把输出重定向到同一个文件里.
上面的程序可以通过 -i 参数做的更简单些. -i 把源文件更名然后从这个更名的源文件里读取.最后把处理后的数据写入源文件. 如 果 -i 后跟有其他字符串, 这个字符串与源文件名合成后来生成一个新的文件名. 此文件会被用来储存原始文件以免被 -i 参数覆盖.
这个例子把所有 php 字符替换为 perl :
$ perl -i -pe 's/\bPHP\b/Perl/g' file.txt
程序读取文件的每一行, 然后替换字符, 处理后的数据重新写入( 即覆盖 ) 源文件. 如果不想覆盖源文件, 可以使用
$perl -i.bak -pe 's/\bPHP\b/Perl/g' file.txt
这里处理过的数据写入 file.txt , file.txt.bak 是源文件的备份.

2009年2月4日星期三

归来

2009年,春节,和莹莹去了一趟西双版纳
见识了云,见识了山,见识了漂亮的大蝴蝶
酸甜苦辣的一趟旅程,是美丽生活的小插曲

zzzzZZZZ

zzzzZZZZ