2012年03月07日

perl -e “use 模块名称;”

如果某个模块已经安装,执行不报错

如果没有安装会报错显示缺少该模块

2010年07月27日
for对很多批处理新手来说可能是最不好理解的,而微软的帮助又极为苦涩难懂,所以我想把我所了解的for
尽可能以最简单的方式写出来。

当然,因为是自己的理解,难免会有错,还请各位指出。好了,开始。

1.没有任何参数的for

格式为:for %%i in (set) do command

%%i 为变量

set为一个文件或者一组文件,其实就是一个集合。可用通配符,比如*.txt。

command 是要执行的命令。

看个例子:

有个文件夹,有如下文件:
a.txt
b.mp3
c.mp3
c.wma
a.rm
e.bat

你想显示里面的扩展名为mp3的文件,你会用什么命令呢?当然是dir了,dir *.mp3。

同样的,for也可以来实现,如下:

for %%i in (*.mp3) do echo %%i

这如何理解?

for会先从括号里面执行,因为括号里面是*.mp3,所以for会先得到当前目录下所有的扩展名是mp3的文件,并把它们作为一个集合,而每个文件名就是一个元素,像这样{b.mp3,c.mp3},然后用%%i依次代替每个元素,之后做do后面的命令。

具体过程如下:

用%%i代替b.mp3,然后执行echo %%i,显示b.mp3

用%%i代替c.mp3,再执行echo %%i,显示c.mp3

没有元素了,for就停止了。

当然,()里面不局限于一个文件或者通配符,可以有多个,比如:

for %%i in (*.mp3,*.wma) do echo %%i   也是可以的。

注意:do 后面可以跟任何命令,不要局限于echo,这里只是演示。

2. 含有/L的for

格式为:for /L %%i in (start,step,end) do command

这个表示以增量形式从start到end的一个数字序列,步长是step,就是每次的增量是step

比如:(1,1,5) 将产生序列 1 2 3 4 5,(1,2,9) 将产生1 3 5 7 9序列。

这有什么用呢?

举个例子,你想同时打开3个记事本程序,可以这样:

for /L %%i in (1,1,3) do notpad.exe

如何理解?

还是从括号先执行,产生集合{1,2,3},然后用%%i依次代替集合中的每个元素,之后执行do后面的命令。

当然这里每次%%i替换集合里面的元素是没有意义的,因为我们并没有在do后面的命令中用到%%i,但是你不能阻止%%i代替每个元素。

因为有3个元素,所以do后面的命令执行3次就停止了。

再举一个例子,加入你要显示1到20之间的奇数,怎么办,可以如下:

for /L %%i in (1,2,20) do echo %%i

同样是先产生集合{1,3,5,7,9,11,13,15,17,19},然后用%%i依次代替每个元素,之后执行do后面的echo %%i

这个例子就体现出变量%%i会始终代替集合中的每个元素。

3.含有/F的for
格式:
FOR /F ["options"] %%i IN (file) DO command

FOR /F ["options"] %%i IN ("string") DO command

FOR /F ["options"] %%i IN ('command') DO command

这个可能是最常用的,也是最强的命令,主要用来处理文件和一些命令的输出结果。

file代表一个或多个文件

string 代表字符串

command代表命令

["options"] 可选

对于FOR /F %%i IN (file) DO command

file为文件名,按照官方的说法是,for会依次将file中的文件打开,并且在进行到下一个文件之前将每个文件读取到内存,按照每一行分成一个一个的元素,忽略空白的行,看个例子。

假如文件a.txt中有如下内容:

第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

你想显示a.txt中的内容,会用什么命令呢?当然是type,type a.txt

for也可以完成同样的命令:

for /f %%i in (a.txt) do echo %%i

还是先从括号执行,因为含有参数/f,所以for会先打开a.txt,然后读出a.txt里面的所有内容,把它作为一个集合,并且以每一行作为一个元素,所以会产生这样的集合,

{“第1行第1列 第1行第2列 第1行第3列”, rem 第一个元素

“第2行第1列 第2行第2列 第2行第3列”, rem 第二个元素

“第3行第1列 第3行第2列 第3行第3列”}   rem 第三个元素

集合中只有3个元素,同样用%%i依次代替每个元素,然后执行do后面的命令。

具体过程:

用%%i代替“第1行第1列 第1行第2列 第1行第3列”,执行do后面的echo %%i,显示“第1行第1列 第1行第2列 第1行第3列”,

用%%i代替“第2行第1列 第2行第2列 第2行第3列”,执行echo %%i,显示“第2行第1列 第2行第2列 第2行第3列”,

依次,直到每个元素都代替完为止。

为了加强理解/f的作用,请执行一下两个命令,对比即可明白:

for /f %%i in (a.txt) do echo %%i rem 这个会显示a.txt里面的内容,因为/f的作用,会读出a.txt中
的内容。

for %%i in (a.txt) do echo %%i rem 而这个只会显示a.txt这个名字,并不会读取其中的内容。

通过上面的学习,我们发现for /f会默认以每一行来作为一个元素,但是如果我们还想把每一行再分解更小的内容,该怎么办呢?不用担心,for命令还为我们提供了更详细的参数,使我们将每一行分为更小的元素成为可能。

它们就是:delims和tokens

delims 用来告诉for每一行应该拿什么作为分隔符,默认的分隔符是空格和tab键

比如,还是上面的文件,我们执行下面的命令:

for /f "delims= " %%i in (a.txt) do echo %%i

显示的结果是:

第1行第1列
第2行第1列
第3行第1列

为什么是这样的呢。因为这里有了delims这个参数,=后面有一个空格,意思是再将每个元素以空格分割,默认是只取分割之后的第一个元素。

执行过程是:

将第一个元素“第1行第1列 第1行第2列 第1行第3列”分成三个元素:“第1行第1列” “第1行第2列” “第1行第3列”,它默认只取第一个,即“第1行第1列”,然后执行do后面的命令,依次类推。

但是这样还是有局限的,如果我们想要每一行的第二列元素,那又如何呢?

这时候,tokens跳出来说,我能做到。

它的作用就是当你通过delims将每一行分为更小的元素时,由它来控制要取哪一个或哪几个。

还是上面的例子,执行如下命令:

for /f "tokens=2 delims= " %%i in (a.txt) do echo %%i

执行结果:

第1行第2列
第2行第2列
第3行第2列

如果要显示第三列,那就换成tokens=3。

同时tokens支持通配符*,以及限定范围。

如果要显示第二列和第三列,则换成tokens=2,3或tokens=2-3,如果还有更多的则为:tokens=2-10之类的。

此时的命令为:

for /f "tokens=2,3 delims= " %%i in (a.txt) do echo %%i %%j

怎么多出一个%%j?

这是因为你的tokens后面要取每一行的两列,用%%i来替换第二列,用%%j来替换第三列。

并且必须是按照英文字母顺序排列的,%%j不能换成%%k,因为i后面是j

执行结果为:

第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

对以通配符*,就是把这一行全部或者这一行的剩余部分当作一个元素了。

比如:

for /f "tokens=* delims= " %%i in (a.txt) do echo %%i

执行结果为:

第1行第1列 第1行第2列 第1行第3列
第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

其实就跟for /f %%i in (a.txt) do echo %%i的执行结果是一样的。

再如:

for /f "tokens=2,* delims= " %%i in (a.txt) do echo %%i %%j

执行结果为:

第1行第2列 第1行第3列
第2行第2列 第2行第3列
第3行第2列 第3行第3列

用%%i代替第二列,用%%j代替剩余的所有

最后还有skip合eol,这俩个简单,skip就是要忽略文件的前多少行,而eol用来指定当一行以什么符号开始时,就忽略它。

比如:

for /f "skip=2 tokens=*" %%i in (a.txt) do echo %%i

结果为:

第3行第1列 第3行第2列 第3行第3列

用skip来告诉for跳过前两行。

如果不加tokens=*的话,执行结果为:

第3行第1列

不知道怎么回事。

再如,当a.txt内容变成:

.第1行第1列 第1行第2列 第1行第3列
.第2行第1列 第2行第2列 第2行第3列
第3行第1列 第3行第2列 第3行第3列

执行for /f "eol=. tokens=*" %%i in (a.txt) do echo %%i结果是:

第3行第1列 第3行第2列 第3行第3列

用eol来告诉for忽略以“.”开头的行。

同样也必须加tokens=*,否则只会显示“第3行第1列”,还是不知道怎么回事。

好了,关于for的/f参数中的file就先说到这,有时间再写其他的,如果有什么疑问,可以留言交流。

下次是关于for的/f参数中的string。
2009年11月26日

介绍性指南

mod_perl 是个庞大而复杂的工具,它内建了许多模块帮助你方便地构建动态网站。这篇指南的目的是帮助你构建一个良好的 mod_perl 模块,并从中理解 mod_perl 的实现技术。我并不推荐使用这里介绍的技术来建立一个大型站点,尤其对于一个刚刚涉足 mod_perl 的人来说。但我推荐大家可以深入看一下它的一些内建的方案,比如 Mason, AxKit, EmbPerl, Apache::ASP 和 PageKit 等等。你需要什么?

本指南假设你已经有过安装和测试 mod_perl 的经验。以及较新版本的 Apache 的安装经验。因为有可能你需要在你的机器上实现时适当的修改本文提供的配置。我们需要你安装一些模块并且需要进入 Apache 的配置目录作修改。所以最好你有 root 权限来做这些事情。当然你还需要一个文本编辑器。切入正题

mod_perl 模块也是 Perl 模块,但它有较为特别的设计。最方便的创建一个 Perl 模块的方法就是使用标准的 Perl 分发自带的工具 h2xs 。你可以在命令行模式键入 h2xs 来看看它的参数列表。现在,到一个适当的目录开始一个新项目,键入:

   h2xs -AX -n Apache::Tutorial::First

h2xs 将会创建目录 Apache, 以及其他一些子目录.现在进入最深一级的目录看看:

   cd Apache/Tutorial/First

在这个新目录里面,你可以看到 6 个文件: README, Changes, First.pm, MANIFEST, Makefile.PL 和 Apache-Tutorial-First.t。它们的作用如下:

  • README

这个文件包含一些安装信息,模块依赖性,版权信息等

  • Changes

这个文件作为你的项目的修改日志(changelog)文件

  • First.pm

这是主模块文件,包含你的 mod_perl 句柄代码(handler code)。

  • MANIFEST

本文件用于自动构建 tar.gz 类型的模块版本分发。这样你就可以把你的模块拿到 CPAN 发布或者分发给其他人。它包含了你在这个项目中所有文件的列表。

  • Makefile.PL

这是标准的 Perl Makefile 构造器。用于创建 Makefile.PL 文件来编译该模块。

  • Apache-Tutorial-First.t

针对该模块的一些测试脚本。默认情况下它只是检查模块的载入,你可以添加一些新的测试单元。

好了,现在我们开始把 First.pm 变为可工作的 mod_perl 模块。使用文本编辑器打开该文件,修改后的内容如下:

package Apache::Tutorial::First;
use strict;
use vars qw/$VERSION/;
use Apache::Constants;
$VERSION = 0.01;
sub handler {
  my $r = shift;
  $r->send_http_header('text/html');
  print "<html><body>Hello World</body></html>";
  return OK;
}
1;

不要忘记文件末尾的”1;”,对于 Perl 来说,一个模块最后返回的非零值表示该模块已经被成功编译。

[编辑] 安装你的模块

h2xs 工具使我们的模块安装工作极为方便。在和你的 First.pm 文件相同的目录中。键入:

   perl Makefile.PL
   make
   make test

如果 make test 成功的话,你需要以 root 身份执行:

   make install

这样你就把你的模块安装到了 perl 的库目录(library directory)。添加该模块为 Apache 的一个句柄(handler)

现在我们需要进入 Apache 配置目录来修改配置文件,使我们的模块作为 Apache 内容处理阶段的处理器。打开 httpd.conf 文件,在末尾加入如下配置:

<Location /mod_perl_tutorial>

 SetHandler perl-script
 PerlHandler Apache::Tutorial::First

</Location>

然后保存配置文件,并且重新启动 apache 服务器:

   apachectl stop
   apachectl start

现在使用浏览器访问 http://localhost/mod_perl_tutorial ,你将如期的看到显示 “Hello World” 页面。

[编辑] 这里都发生了些什么?

好,在这里都发生了什么事情呢?

当 Apache 启动的时候,它读取它的配置指令并把适当的命令传递给相应的处理该命令的模块。这里有两个相关的指令 SetHandler 和 PerlHandler.

第一个指令 SetHandler 由 mod_mime 模块处理,该指令表示使用什么模块作为处理请求的主要部分。这里所设置的 perl-script 表示使用 mod_perl 来处理请求。

第二个指令 PerlHandler 由 mod_perl 模块来处理,它只是简单的说明使用我们的模块来处理请求的主要部分。有一点需要注意,无论何时在你有一个 PerlHandler 时,你需要相应的 SetHandler perl-script 配置指令。这样才能使你的 mod_perl 代码起作用。我总是认为这是一个弱点,但这将涉及 Apache 内部的处理机制,所以在将来这也很难改变。

现在请求来了,Apache 查看用什么模块来处理相应的 URI 并且在这里决定使用 mod_perl,而 mod_perl 知道它必须把请求发送给我们的模块,并调用我们模块的 handler() 函数作为 Apache::Request 对象的第一个参数。而我们的 handler() 函数的返回值决定了下一步 Apache 将要做什么。现在我们知道返回值 OK 意味着一切成功。 OK 是个从 Apache::Constants 模块导出的常量。

[编辑] 调试

如果你没有看到 “Hello World”, 那你可能看到了一个错误页面,或者其他什么完全不同的。第一步去查看错误日志看看到底是什么发生了错误。我习惯于在浏览器中请求后立即查看错误日志。你可以使用 tail 工具:

   tail -f /path/to/apache/logs/error_log

(使用你的真实 error_log 路径替换上面的路径。如果你不肯定它在哪里,查看你的 httpd.conf 文件的 ErrorLog 指令部分)

现在重新载入页面,然后 error_log 将告诉你什么地方出现了问题。更多的关于 perl 调试,请参见 perldebug.

[编辑] 加入更多

现在如果你想要针对上面的情况作一些修改,该如何做呢?不幸的,唯一一种安装模式如下:

  • 修改你的 First.pm 文件
  • 重新以 root 身份运行 make install
  • 重新启动 Apache

这也许很麻烦,特别是重新启动 Apache。针对这个问题,我们可以另外安装一个特别设计的模块来避免每次这样麻烦的做。首先你需要从 CPAN 下载并安装 Apache::Reload 模块(除非你已经使用 mod_perl 1.26 或者更高版本)。在这里 http://search.cpan.org/search?dist=Apache-Reload 下载。

解开 tar.gz 文件并进入新目录,执行:

   perl Makefile.PL
   make

然后到 root 身份执行:

   make install

现在再次打开 httpd.conf 文件,加入:

   PerlInitHandler Apache::Reload

这将测试所有有所改变的模块并在必要时自动重新载入新模块。这对于开发来说很有用,但会有性能损失,所以在开发完成之后,就将该特性关闭。

[编辑] 阅读更多

从这里开始你有很多事情需要去做。Apache API 本身就十分庞大,大多数都可以通过 perldoc Apache 看到相应的文档. 现在这个模块基本上没有什么价值,因为只有一个 URI 可以用于被该模块所控制( http://server/mod_perl_tutorial ),这使得它变得不够灵活。为了使一个模块可以处理多个 URI ,有许多解决办法,但最好的还是推荐使用 Apache::Dispatch 模块。可以在 CPAN 下载 http://search.cpan.org/search?dist=Apache-Dispatch. Apache::Dispatch 允许你保留标准的 mod_perl handler 构架,同时还允许多个函数和多个URIs 被派发。

接下来我不建议象例子中一样直接向浏览器输出内容。请考虑使用一些常用的模版技术,比如 Template-Toolkit, HTML::Template, 更甚于使用 XSLT 或者 XPathScript (有很多很多这样的模版技术可选,我们希望有一天可以有文章来讨论这些技术来帮助你来选择)。

2009年11月24日

下面是我在aix5.3上运行的一段发邮件的perl程序的一部分:
my $senderh = new Mail::Sender;
print "[SendEmail] 开始发送邮件5\n";
print $sender;
if ($senderh->MailFile({
smtp => $stmp,
from => $sender,
to =>$cc,
#cc =>$cc,
subject => $title,
msg => $content,
auth => ‘LOGIN‘, #LOGIN, PLAIN, CRAM-MD5 and NTLM
authid => $user,
authpwd => $passwd,
#charset=>’GB2312′,
#encoding=>’GB2312′,
b_charset=>’GB2312′,
file => "$file",
}) < 0) {
showTime(); print "[SendEmail] $Mail::Sender::Error\n";
return $false;
}
showTime(); print "[SendEmail] 发送邮件通知成功\n";
return $true;

以前是能够发送成功的,但是我最近又运行了一次,报错了,错误是:
Authentication protocol LOGIN is not accepted by the server

难道是什么服务被停止了吗? 哪位高手来指点一下呀!

2009年11月20日
PERL 语言中的q,qw,qr,qx,qq……符号用法(2008-07-22 09:54:31)
在perl语言中,有两个特殊而常用的符号qq qw,分别解释如下:
qq{foobar}的意思为意思为双引号字符串,可内插变量
相当于 "foobar"
qw{foo bar}的意思为用空格分解字符串,得到列表,相当于如下语句
split(‘ ‘,’foo bar’) 得到的结果是’foo’,'bar’

字符串比较等于用 eq

q运算符对’号转义的方式
$someword = ‘i \’ve some money’;
可以等价于:
$someword = q~i ‘ve some money~;

qq运算符对"号转义的方式
$someword = "i say \"ok!\".";
可以等价于:
$someword = qq~i say "ok!".~;

qw代表用空格来分隔元素,得到列表
@list = ("perl","Regular","network","web");
可以等价于:
@list = qw(perl Regular network web);

qr代表创建正则
$myword = "cnangel";
$replaceword = qr(cnangel);
$finalword = "ok" if ($myword =~ $replaceword);

引号执行运算符(quoted execution operator),qx//
qx/uname -p -r/

q 和 qq 运算符的特点:
※ q 和 qq 必须是一个标识符,而不是标识符的部分。例如:
q (abc)      用 () 作为分界符
q(abc)       用 () 作为分界符
q xabcx      用 x 作为分界符
都是合法的,而
qxabcx 就会被当作是一个标识符来处理,有谁会想到 qxabcx 居然是一个 q 运算式呢?

※ q 和 qq 后面的空格并不会影响语法,但是任何非空字符(不是空格、不是 TAB 字符、
   不是换行符)则会被当作界限符来使用。

※ 如果 q 和 qq 使用一些特殊的符号的时候,则必须配对。比如:< 只能和 >; 在一起
   用来当作界限符,而不能只用两个 < 作为界限符。而 | 则只能和它自己作为一对界
   限符。这些特殊的符号有:()、{}、[]、<>;

$myword = "cnangel";
$replaceword = qr(cnangel);
$finalword = "ok" if ($myword =~ $replaceword);

@list = ("perl","Regular","network","web");
可以等价于:
@list = qw(perl Regular network web);

$someword = ‘i \’v some money’;
可以等价于:
$someword = q~i ‘v some money~;

q// is generally the same thing as using single quotes – meaning it doesn’t interpolate values inside the delimiters.
qq// is the same as double quoting a string. It interpolates.
qw// return a list of white space delimited words. @q = qw/this is a test/ is functionally the same as @q = (‘this’, ‘is’, ‘a’, ‘test’)
qx// is the same thing as using the backtick operators.
I’ve never used qr//, but it’s got something to do with compiling regex’s for later use.
引自 http://blog.chinaunix.net/u1/52454/showart_1005919.html