2008年6月25日 星期三
Get host name in perl script.
Want to get the host name which the perl script running on.
====
Solution:
The macro `hostname` helps us to get host name.
Note that `hostname` is not 'hostname'. You need to use `, the key which also send ~ on keyboard.
i.e.
$host_name = `hostname`;
Get the script location, full name rather than working directory.
Want to get the location of the script rather than the working directory.
For example, there is a perl script "C:\ooxx\xxoo\aabb.pl". You want to get the directory "C:\ooxx\xxoo".
====
Solution:
For code,
use Cwd; $workingDir = getcwd; |
If you at "C:" and give the command "C:\ooxx\xxoo\aabb.pl", then the current working directory would be "C:".
To get "C:\ooxxx\xxoo", the location of the script, just use
$theSciptFullName = $0; |
at the start of the code. When the script just start, the $0 stores the script's full path, that is "C:\ooxx\xxoo\aabb.pl". You can derive the location of the script from the script's full name.
2008年5月12日 星期一
Using fork() exec() like C, Unix environment in Perl.
In UNIX, the child process who called exec() will use the same process id returning by fork.
However, exec() in perl is not like the exec() in UNIX.
int pid = fork();
if (pid) {
// parent
sleep(...);
kill(pid);
}
else {
// child
exec(.....);
}
In this case, the parent process will kill child process by calling "kill(pid)" in c code executing under UNIX.
But things go different in Perl
The similar code
$pid = fork();
if ($pid) {
sleep(...);
kill 'KILL', $pid;
}
else {
exec(....);
}
Although the parent process can still kill child by using "kill 'KILL', $pid", the process triggered by exec(....) still alive.
Since setpgrp() does not always work, the solution of mine is using module WIn32::Process.
http://www.xav.com/perl/site/lib/Win32/Process.html
(If the link became unavailable, just goole "Perl Win32::Process")
By using Win32::Process to open the process, you can get process id by method GetProcessID().
It seems that there is also a function "Kill" to kill the process.
However, I am not sure whether it works well. Meanwhile, it may not also close all its' child process.
I use
kill 'SIGABRT', $ProcessObj->GetProcessID();
instead.
2008年5月9日 星期五
Helpful tutorial for Perl XML::Parser
http://www.perlmonks.org/?node_id=62782
Following are part of the contents of this web page.
Let me emphasis that the following contents are copied from
http://www.perlmonks.org/?node_id=62782
========
XML::Parser Tutorial by OeufMayo on Mar 07, 2001 at 20:54 UTC ( #62782=perltutorial: print w/ replies, xml ) We all agree that Perl does a really good job when it comes to text extraction, particulary with regular expressions. The XML is based on text, so one might think that it would be dead easy to take any XML input and have it converted in the way one wants. Unfortunately, that is wrong. If you think you'll be able to parse a XML file with your own homegrown parser you did overnight, think again, and look at the XML specs closely. It's as complex as the CGI specs, and you'll never want to waste precious time trying to do something that will surely end up wrong anyway. Most of the background discussions on why you have to use CGI.pm instead of your own CGI-parser apply here. The aim of this tutorial is not to show you how XML should be structured and why you shouldn't parse it by hand but how to use the proper tool to do the right job. I'll focus on the most basic XML module you can find, XML::Parser. It's written by Larry Wall and Clark Cooper, and I'm sure we can trust the former to make good software (rn and patch are his most famous programs) Okay, enough talk, let's jump into the module! This tutorial will only show you the basics of XML parsing, using the easiest (IMHO) methods. Please refer to the perldoc XML::Parser for more detailed info. I'm aware that there are a lot of XML tools available, but knowing how to use XML::Parser can surely help you a lot when you don't have any other module to work with, and it also helped me to understand how other XML modules worked, since most of them are built on top of XML::Parser. The example I'll use for this tutorial is the Perlmonks Chatterbox ticker that some of you may have already used. It looks like this: <CHATTER><INFO site="http://perlmonks.org" sitename="Perl Monks"> Rendered by the Chatterbox XML Ticker</INFO> <message author="OeufMayo" time="20010228112952"> test</message> <message author="deprecated" time="20010228113142"> pong</message> <message author="OeufMayo" time="20010228113153"> /me test again; :)</message> <message author="OeufMayo" time="20010228113255"> <a href="#">please note the use of HTML tags</a></message> </CHATTER> Thanks to deprecated for his unaware intervention here ( The astute reader will notice that in the CB ticker, a 'user_id' has shown up recently. Since it wasn't there when I took my 'snapshot' of the CB, I'll ignore it, but don't worry the code below won't break at all, precisely because I used a proper parser to handle that for me! ) Let's assume we want to output this file in a readable way (though it'll still be barebone). It doesn't handles links and internal HTML entities. It only gets the CB ticker, parses it and prints it, you have to launch it again to follow the wise meditations and the brilliant rethoric of the other fine monks present at the moment. 1 #!/usr/bin/perl -w 2 use strict; 3 use XML::Parser; 4 use LWP::Simple; # used to fetch the chatterbox ticker 5 6 my $message; # Hashref containing infos on a message 7 8 my $cb_ticker = get("http://perlmonks.org/index.pl?node=chatterbox+ +xml+ticker"); 9 # we should really check if it succeeded or not 10 11 my $parser = new XML::Parser ( Handlers => { # Creates our parse +r object 12 Start => \&hdl_start, 13 End => \&hdl_end, 14 Char => \&hdl_char, 15 Default => \&hdl_def, 16 }); 17 $parser->parse($cb_ticker); 18 19 # The Handlers 20 sub hdl_start{ 21 my ($p, $elt, %atts) = @_; 22 return unless $elt eq 'message'; # We're only interrested in +what's said 23 $atts{'_str'} = ''; 24 $message = \%atts; 25 } 26 27 sub hdl_end{ 28 my ($p, $elt) = @_; 29 format_message($message) if $elt eq 'message' && $message && $ +message->{'_str'} =~ /\S/; 30 } 31 32 sub hdl_char { 33 my ($p, $str) = @_; 34 $message->{'_str'} .= $str; 35 } 36 37 sub hdl_def { } # We just throw everything else 38 39 sub format_message { # Helper sub to nicely format what we got fro +m the XML 40 my $atts = shift; 41 $atts->{'_str'} =~ s/\n//g; 42 43 my ($y,$m,$d,$h,$n,$s) = $atts->{'time'} =~ m/^(\d{4})(\d{2})( +\d{2})(\d{2})(\d{2})(\d{2})$/; 44 45 # Handles the /me 46 $atts->{'_str'} = $atts->{'_str'} =~ s/^\/me// ? 47 "$atts->{'author'} $atts->{'_str'}" : 48 "<$atts->{'author'}>: $atts->{'_str'}"; 49 $atts->{'_str'} = "$h:$n " . $atts->{'_str'}; 50 print "$atts->{'_str'}\n"; 51 undef $message; 52 } Step-by-step code walkthrough: Lines 1 to 4 Initialisation of the basics needed for this snippet, XML::Parser, of course, and LWP::Simple to get the chatterbox ticker. Line 8 LWP::Simple get the requested URL, and put the content of the page in the $cb_ticker scalar. Lines 11 to 16 The most interesting part, no doubt. We create here a new XML::Parser object. The Parser can come in different styles, but when you have to deal with simple data, like the CB ticker, the Handlers way is the easiest (see also the Subs style, as it is really close to this one). For this object, we define four handlers subs, each representing a different state in the parsing process. The 'Start' handler is called whenever a new element (or tag, HTML-wise) is found. The sub given is called with the expat object, the name of the element, and a hash containing all the atrributes of this element. The 'End' is called whenever an element is closed, and is called with the same parameters as the 'Start', minus the attributes. The 'Char' handler is called when the parser finds something which is not mark-up (in our case, the text enclosed in the <message> tag). Finally, the 'Default' handler is called, well, by default, when anything else matching the three other handlers is called. Line 17 The line that does all the magic, parsing and calling all your subs for you at the right moment. Lines 20-25: the Start handler We only want to deal with the <message> elements (those containing what it is being said in the Chatterbox) so we'll happily skip every other element. We got a hash with the attributes of the element, and we're going to use this hash to store the string that will contain the text to be displayed in the $atts{'_str'} Lines 27-30: the End handler Once we've reached the end of a message element, we format all the info we have gathered and prints them via the format_message sub. Lines 32-35: the Char handler This sub gets all the strings returned by the parser and appends it to the string to be finally displayed Line 37: the Default handler It does nothing, but it doesn't have to figure out what to do with this! Lines 39-52 This subroutine mangles all the info we got from the XML file, with bad regexes and all, and prints the formatted text in a hopefully readable way. Please note that XML::Parser handled all of the decoding of the < and > entities that were included in the original XML file We now have a complete and simple parser, ready to analyse, extract, report everything inside the Chatterbox XML ticker! That's all for now, here are some links you may find useful: Most of mirod's nodes (and especially his review of XML::Parser) davorg's Data Munging with Perl Thanks to mirod, arhuman and danger for the review |
2008年4月18日 星期五
Write XML Documents by using Perl
http://search.cpan.org/~josephw/XML-Writer-0.604/Writer.pm
http://www.xml.com/pub/a/2001/04/18/perlxmlqstart1.html
For simplely, you can refer the usage of XML::Writer.
Following are part of content in these web pages, you can look out for them directly.
========
use XML::Writer; use IO::File; my $output = new IO::File(">output.xml"); my $writer = new XML::Writer(OUTPUT => $output); $writer->startTag("greeting", "class" => "simple"); $writer->characters("Hello, world!"); $writer->endTag("greeting"); $writer->end(); $output->close(); |
========
use XML::Writer; require "files/camelid_links.pl"; my %camelid_links = get_camelid_data(); my $writer = XML::Writer->new(); $writer->xmlDecl(); $writer->startTag('html'); $writer->startTag('body'); foreach my $item ( keys (%camelid_links) ) { $writer->startTag('a', 'href' => $camelid_links{$item}->{url}); $writer->characters($camelid_links{$item}->{description}); $writer->endTag('a'); } $writer->endTag('body'); $writer->endTag('html'); $writer->end(); |
2008年4月8日 星期二
The type 'System.Web.UI.ScriptManager' is ambiguous: it could come from assembly
Encounter error message,
The type 'System.Web.UI.ScriptManager' is ambiguous: it could come from assembly 'C:\WINDOWS\assembly\GAC_MSIL\System.Web.Extensions\1.0.61025.0__31bf3856ad364e35\System.Web.Extensions.dll' or from assembly 'C:\WINDOWS\assembly\GAC_MSIL\System.Web.Extensions\3.5.0.0__31bf3856ad364e35\System.Web.Extensions.dll'. Please specify the assembly explicitly in the type name. |
You may encounter this problem after migrating your application to other host.
========
Solution:
My solution is
1.Delete all files in your bin folder. You may want to backup all of them first.
2.Remove the reference of System.Web.Extensions and System.Web.Extensions.Design from your project(application). They should be version 1.0.61025.0.
3.Re-add System.Web.Extensions and System.Web.Extensions.Design into your project(application). Be sure to include the new version, 3.5.0.0.
4.Modify these two line in your Web.config.
<add assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <add assembly="System.Web.Extensions.Design, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> |
change the version attribute
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> <add assembly="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"> |
There are two solutions I refered.
http://weblogs.asp.net/javiervillarreal/archive/2008/01/30/the-type-system-web-ui-scriptmanager-is-ambiguous-it-could-come-from-assembly.aspx
and
http://www.eggheadcafe.com/aspnet/how-to/1858840/the-type-systemwebuis.aspx
2008年4月7日 星期一
Very Good PKZIP Command Line Reference
This is the origin page.
http://www.uwm.edu/~dtoth/pkzip.html
Following is the content "COPY" from the link shown above.
====
PKZIP
Command Line Reference
This document was created to introduce you to the
command line version of PKZIP. One of the significant differences between
this version of PKZIP and previous versions of PKZIP/PKUNZIP is the consolidation
of compression and extraction (zip/unzip) functionality into a single program.
In other words, the same program compresses and extracts files.
Additionally, the command line syntax has been changed. This was done to
make PKZIP easier to understand and use for the novice and power user alike.
Hopefully, you will find all of the functionality of previous versions
of PKZIP with a simpler more intuitive user interface.
If you have used earlier command line versions of
PKZIP (e.g. PKZIP 2.04g), you may find the PKZIP
Command Line Translation Table helpful.
Please keep in mind that although this document does
include basic information to help you get started using PKZIP, it is not
a user's manual. The Registered and Licensed versions of PKZIP come with
extensive documentation including a comprehensive user's manual. The PKZIP
User's Manual includes such things as tutorials as well as in depth discussions
of PKZIP's advanced features.
PKZIP Usage:
Usage: pkzip25 [command] [options] zipfile [@list]
[files...]
Examples:
View .ZIP file contents:
pkzip25 zipfile
Create a .ZIP file: pkzip25
-add zipfile file(s)...
Extract files from .ZIP:
pkzip25 -extract zipfile
These are only basic examples of PKZIP's capability
PKZIP Command Reference:
An alphabetical listing of available PKZIP commands
and options follows. You may wish to scroll through the entire list or
click on one of the hyperlinks below to go directly to the specified command/option
section.
PKZIP Commands:
Add | Default | Header | Sfx |
PKZIP Options:
204 | ID Locale (OS/2) Locale (DOS/UNIX) | NameSfx | Sfx |
This document contains reference information on every
PKZIP command and option. For each command/option, the following information
is provided:
Category: | Represents: |
Name/Description | The full name of the command/option and a brief description of what that command/option does. If the command/option can be configured |
Value(s) | The value(s) associated with this command/option, including the "default" value for each. If a command/option does not have an |
Example usage | An example of how to include this command/option in your PKZIP command line, including possible abbreviations. For most options, you can abbreviate the command/option. These abbreviations are illustrated in the examples used in this appendix. |
Used with | This command can be used for compression, extraction, viewing, testing, a combination, or as a stand-alone (none of the above). |
Note: Most commands and options documented
here work in all versions of PKZIP. In instances where a command, option,
or suboption is specific to a platform or operating system, the document
will indicate as much. (e.g. UNIX,
DOS, OS/2).
Information on each command/option follows:
PKZIP
Command Line Translation Table
PKZIP 2.04 Command: | PKZIP 2.50 Command/Option |
pkzip | pkzip25 -add |
-b<drive:path> | -temp=drive:path |
-c/-C | -comment(all,unchanged,add,freshen,update,none) |
-d | -delete |
-e[x|n|f|s|0] | -level (0-9) |
-ex | -maximum |
-en | -normal |
-ef | -fast |
-es | -speed |
-e0 | -store |
-f | -freshen |
-h | -help |
-i | -add=incremental |
-i- | -add=-incremental |
-j<h,r,s> | -mask=all (hidden,system,readonly) |
-J<h,r,s> | -mask=none (default) |
-k | -zipdate=retain |
-m[u|f] | -move (with /add=update or /add=freshen) |
-o | -zipdate (newest,oldest,retain,none) |
-p | -path (current,relative,specify) |
-P | -path=full |
-r | -recurse |
-rp/-rP | -directories (current,full,relative,specify,none) |
-s[password] | -password (or -password=xxxx) |
-t<date> | -after=mmddyy (or mmddyyyy) |
-T<date> | -before=mmddyy (or mmddyyyy) |
-u | -add=update |
-v | -view (brief,details,normal) |
-w<h,s>W<h,s> | -attributes (hidden,system,readonly,all,none) |
-x<filename | -exclude=filename |
-x@listfile | -exclude=@listfile |
-z | -header |
-& | -span (to force if not detected) |
-$[d] | -volume=drive |
pkunzip | pkzip25 -extract |
-c[m] | -console (-more) |
-d | -directories |
-e[r][c|d|e|n|p|s] | -sort (crc,date,extension,name,ratio,size,natural,none) |
-f | -extract=freshen |
-h | -help |
-j<h,r,s> | -mask=all (default) (hidden,system,readonly) |
-J<h,r,s> | -mask=none |
-n | -extract=freshen |
-o | -overwrite (prompt,all,never) |
-p[a/b][c][#] | |
-s[password] | -password (or -password=password) |
-t | -test (all,freshen,update) |
-v | -view (brief,details,normal) |
-x<filespec> | -exclude=filename |
-x@listfile | -exclude=@listfile |