<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-20554462</id><updated>2011-12-03T23:53:09.454+08:00</updated><title type='text'>kk's blog</title><subtitle type='html'>the journal of the linux surfing</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>62</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20554462.post-8211467478027776428</id><published>2011-03-27T13:16:00.001+08:00</published><updated>2011-03-27T13:17:01.984+08:00</updated><title type='text'>How to set up a mail server on a GNU / Linux system</title><content type='html'>&lt;a href="http://flurdy.com/docs/postfix/"&gt;How to set up a mail server on a GNU / Linux system&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Editions&lt;br /&gt;List of different versions of this document.&lt;br /&gt;Introduction&lt;br /&gt;Brief description of this document.&lt;br /&gt;Aim&lt;br /&gt;Research&lt;br /&gt;Donate&lt;br /&gt;Software&lt;br /&gt;Which software packages are we using and why.&lt;br /&gt;Installation&lt;br /&gt;How to install all packages and which ones.&lt;br /&gt;Distrobution&lt;br /&gt;Base Install&lt;br /&gt;Repositories&lt;br /&gt;Packages&lt;br /&gt;Configuration&lt;br /&gt;Post install, what to configure for each section, with full command examples.&lt;br /&gt;Firewall (Shorewall)&lt;br /&gt;MTA (Postfix)&lt;br /&gt;Database (MySQL)&lt;br /&gt;Pop/IMAP (Courier)&lt;br /&gt;Content Checks (amivisd-new)&lt;br /&gt;Anti-Spam(SpamAssassin)&lt;br /&gt;Anti-Virus (ClamAV)&lt;br /&gt;Policy Check (PostGrey)&lt;br /&gt;Authentication (SASL)&lt;br /&gt;Encryption (TLS)&lt;br /&gt;Webmail (SquirrelMail)&lt;br /&gt;Administration (phpMyAdmin)&lt;br /&gt;Data&lt;br /&gt;Creating the basic stub of data, and how to add your own.&lt;br /&gt;Add users and domains&lt;br /&gt;Common SQL&lt;br /&gt;Test&lt;br /&gt;Testing and troubleshooting each element.&lt;br /&gt;Common problems&lt;br /&gt;Test strategy&lt;br /&gt;Switch debug on&lt;br /&gt;Tail, tail and tail again&lt;br /&gt;Telnet is your friend&lt;br /&gt;Can postfix receive?&lt;br /&gt;Can postfix send?&lt;br /&gt;Can courier read?&lt;br /&gt;Initialize&lt;br /&gt;If receiving an already setup machine, a list of actions to do to initialize and configure it.&lt;br /&gt;Extend&lt;br /&gt;Post working system, detailed instructions on optional features to add.&lt;br /&gt;Remote MX mail backup&lt;br /&gt;Relay recipient lookup&lt;br /&gt;Local file backup&lt;br /&gt;Sender ID &amp; SPF&lt;br /&gt;Spam Reporting&lt;br /&gt;White/Black lists&lt;br /&gt;PGP &amp; S/MIME&lt;br /&gt;Relocation notice&lt;br /&gt;Pop-before-SMTP&lt;br /&gt;Auto Reply&lt;br /&gt;Block Addresses&lt;br /&gt;Throttle Output&lt;br /&gt;Mail Lists&lt;br /&gt;Admin software&lt;br /&gt;Google Apps / GMail&lt;br /&gt;Maildrop, spam folder and vacation messaging&lt;br /&gt;Roundcube webmail client&lt;br /&gt;Elastic Compute Cloud (ec2)&lt;br /&gt;Amazons' hosting service. Used as examples for this howto.&lt;br /&gt;Impressions of EC2&lt;br /&gt;ec2 introduction, tips and hwotos&lt;br /&gt;Using EC2 with this howto&lt;br /&gt;Amazon EC2 Images: AMIs&lt;br /&gt;EC2 Links&lt;br /&gt;Appendix&lt;br /&gt;About author&lt;br /&gt;Contact&lt;br /&gt;Why&lt;br /&gt;References&lt;br /&gt;Software Links&lt;br /&gt;Difference between Ubuntu versions&lt;br /&gt;Download&lt;br /&gt;Todo&lt;br /&gt;Change Log&lt;br /&gt;FAQ&lt;br /&gt; &lt;br /&gt;Return to top.&lt;br /&gt;Editions&lt;br /&gt;Edition State Started Updated Description&lt;br /&gt;1st Released (outdated) 2004-01 2004-02  Based on Mandrake 9.1.&lt;br /&gt;2nd Released (outdated) 2004-02 2004-07  Based on Mandrake 10.x, but valid for all distributions. Very thorough. Includes package description, where to get the sources and binaries, how to build them or which RPMs to use, includes many refrences, etc etc. Starts off with a basic working server, then advances, extends and tightens it in stages.&lt;br /&gt;3rd Released (outdated) 2005-05 2005-11  Based on Ubuntu 5.04, Hoary Hedgehog. More concise simplified guide to get an advanced server working quickly. Now includes SASL &amp; TLS integration.&lt;br /&gt;4th Released (outdated) 2005-10 2005-12  Based on Breezy Badger, Ubuntu 5.10. Includes Postgrey&lt;br /&gt;5th  Released (outdated) 2006-05 2006-11  Based on Dapper Drake, Ubuntu 6.06 LTS.&lt;br /&gt;6th  Scrapped 2006-11 2007-10  Was to be based on Edgy Eft, Ubuntu 6.10 or 7.04. include Domain Key signing. include my mail admin or my catchall aliases admin.&lt;br /&gt;7th  Released 2008-04 2009-06  Updated, based on Ubuntu 8.04 LTS Hardy Heron. Using Amazon EC2 as example. (Tested with 8.10 &amp; 9.04 as well)&lt;br /&gt;8th  Released (superseeded) 2009-05 2009-11  Based on Ubuntu 8.10 (intrepid), then tested with 9.04 (jaunty) &amp; 9.10 (karmic) as well. Using official Ubuntu ec2 as examples.&lt;br /&gt;9th  Released (superseeded) 2009-11 2010-05  Based on Ubuntu 9.10 (karmic) using Canonical's cloud images. Added Roundcube webmail option.&lt;br /&gt;10th (this)  Released 2009-12 2010-12  Based on Ubuntu 10.04 LTS (lucid) using Canonical's cloud images. Tested on 10.10 (maverick)&lt;br /&gt;11th  draft 2010-11 2011-02  Based on Ubuntu 10.10 (maverick) or 11.04 (natty) using Canonical's cloud images.&lt;br /&gt;Further details available in the change log and below in the introduction.&lt;br /&gt;Return to top.&lt;br /&gt;Introduction&lt;br /&gt;Aim&lt;br /&gt;This is a step by step howto guide to set up a mail server on a GNU / Linux system. It is easy to follow, but you end up with a powerfull secure mail server.&lt;br /&gt;The server accepts unlimited domains and users, and all mail can be read via your favourite clients, or via web mail.&lt;br /&gt;It is secure, traffic can encrypted and it will block virtually all spam and viruses.&lt;br /&gt;Return to top.&lt;br /&gt;Research&lt;br /&gt;Dont take my word for it! Research others opinions and methods. Look at my references, look at Postfix.org's howtos, read the excellent books available (E.g. Kyle's or Hildebrandt's), search the web or read the proper documentation.&lt;br /&gt;If you refer to this howto in your own document, or find useful links, then let me know.&lt;br /&gt;Donate&lt;br /&gt;If you found this howto very useful, spread the word and help others?&lt;br /&gt;If this howto was exceptionally useful why not donate me some beer money?&lt;br /&gt;Or buy a postfix book using my amazon affiliate links further down?&lt;br /&gt;Or buy a t-shirt from my t-shirt shop?&lt;br /&gt;Otherwise send me a Thank You note?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;UK&lt;br /&gt;&lt;br /&gt;US&lt;br /&gt;&lt;br /&gt;EU&lt;br /&gt;&lt;br /&gt;Return to top.&lt;br /&gt;Software&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;What software packages have/will I use and why.&lt;br /&gt;OS: Ubuntu Linux&lt;br /&gt;www.ubuntu.com&lt;br /&gt;Ah the age old distro argument... Thankfully this set up should work on most distros. I used to base this howto on Mandrake(now Mandriva), and I started this new edition on a Gentoo box. But I don't have the patience for Gentoo, nor the money to stay with Mandriva Power editions. Why Ubuntu? Its free, simple and slick. As Ubuntu is derived from debian the installations used here will be apt-get based. Please refer to my other editions for details on RPM or source based installations.&lt;br /&gt;MTA: Postfix&lt;br /&gt;www.postfix.org&lt;br /&gt;Simple, free and slick. Yup I am a sucker for anything that works easily.  Postfix is powerfull, well established, but not too bloated, and is security concious from the start.&lt;br /&gt;Pop/IMAP: Courier IMAP&lt;br /&gt;www.courier-mta.org/imap/&lt;br /&gt;My first mail server installtion was with Courier. I have not found a reason to change this as again it is simple, and free.&lt;br /&gt;Database: MySQL&lt;br /&gt;www.mysql.com&lt;br /&gt;Although I use Firebird for my application development, (or Hibernate/C-JDBC hybrids), MySQL is well supported for the sort of lookups required in a mail server.&lt;br /&gt;Content Check: Amavisd-new&lt;br /&gt;www.ijs.si/software/amavisd/&lt;br /&gt;Easy plug in solution for spam, virus checking etc.&lt;br /&gt;Anti-Spam: SpamAssassin&lt;br /&gt;spamassassin.apache.org&lt;br /&gt;Powerfull renowned spam fighting tool.&lt;br /&gt;Anti-Virus: ClamAV&lt;br /&gt;www.clamav.net&lt;br /&gt;Free virus scanner that can be trusted and includes update daemon.&lt;br /&gt;Authentication: Cyrus SASL&lt;br /&gt;www.imc.org/ietf-sasl/&lt;br /&gt;Secure and trusted crypthography technology for authentication of SMTP traffic.&lt;br /&gt;PostGrey&lt;br /&gt;isg.ee.ethz.ch/tools/postgrey/&lt;br /&gt;Postgrey is an excellent little script to stop 99% of all spam. All it does is on first contact for specific from-to combinations, tells the sender server to try again in a little while, which most spammers cant afford to do. When proper servers try again after a few minutes it lets it through.&lt;br /&gt;Encryption: TLS&lt;br /&gt;www.ietf.org/html.charters/tls-charter.html&lt;br /&gt;Secure and trusted crypthography technology for encryption of SMTP traffic. Not too be confused with client encryption technology like GnuPG and S/MIME. They are covered in the extend section. Formerly referenced as SSL.&lt;br /&gt;WebMail: SquirrelMail or Roundcube&lt;br /&gt;www.squirrelmail.org&lt;br /&gt;Easy to set up php based web mail client. Extensive plugin selection.&lt;br /&gt;www.roundcube.net&lt;br /&gt;Ajaxified prettier web mail client. Not quite as solid as SquirrelMail.&lt;br /&gt;Platform: Amazon ec2&lt;br /&gt;aws.amazon.com/ec2&lt;br /&gt;This guide can be installed locally, co-located or in the cloud.&lt;br /&gt;My preference is ec2, and I provide ec2 based examples, however it makes no difference where you install your mail server.&lt;br /&gt;Please see software links appendix for further information about these software packages. In that section there is more links to documentation or forums, and viable alternatives, downloadable packages, versions details etc.&lt;br /&gt;Further software and tweaks are discussed in the extension section.&lt;br /&gt;Also review other peoples opinion on these packages via my references.&lt;br /&gt;Return to top.&lt;br /&gt;Installation&lt;br /&gt;Distrobution&lt;br /&gt;Base Install&lt;br /&gt;Repositories&lt;br /&gt;Packages&lt;br /&gt;&lt;br /&gt;Distribution&lt;br /&gt;This section is different for every distribution and for every version.&lt;br /&gt;This howto is based on Ubuntu and its base of debian which uses apt-get. Therefor this section uses apt packages to its fullest.&lt;br /&gt;For other installation method please refer to previous edition's software links and your own distribution for the documention for other ways of installing. My 2nd edition(outdated) has instructions for Mandriva, general RPM and tarball compiling.&lt;br /&gt;To follow the rest of this howto with another distrobution, you need to ensure all your packages have been installed with the same modules, E.g MySQL lookup on postfix and sasl, php in apache etc.&lt;br /&gt;I have set up mail servers using the 32bit and 64bit x86 platforms, and if all the packages are available then other, E.g. Mac platforms should work too.&lt;br /&gt;Base Install&lt;br /&gt;With installing Ubuntu you have a choice of which base system to install. You may choose server or desktop image or very basic setups. I will assume a server install, but it should not differ.&lt;br /&gt;Or if you have chosen an ec2 based server, you can:&lt;br /&gt;Base it on a Canonical image&lt;br /&gt;Apply my ec2 Ubuntu server suggestions&lt;br /&gt;Use my prebuilt ec2 public images for this postfix mail server&lt;br /&gt;Ps. Please note that after a while Ill stop specifying the use of sudo, as it is up to yourselves if you use it or use a priviliged user, e.g. root.&lt;br /&gt;Repositories&lt;br /&gt;For assistance with repositories, refer to this article on ubuntu's wiki.&lt;br /&gt;A previous edition discussed repository configuration in more detail.&lt;br /&gt;But basically for this you need main and universe, and I also throw in the other "safe" ones: restricted and multiverse (and partner, when available).&lt;br /&gt;sudo vi /etc/apt/source.list &lt;br /&gt;If main and universe already is listed, this is a quick find and replace to add the others all over:&lt;br /&gt;:%s/main un/main restricted multiverse un/g&lt;br /&gt;As mentioned in the previous edition you also might want to find a repository closer to your server.&lt;br /&gt;Packages&lt;br /&gt;You need to install a whole bunch of packages.  We will install them bit by bit. But first check your package sources are correctly pointing to main multiverse restricted universe repositories of your current Ubuntu version.&lt;br /&gt;sudo vi /etc/apt/sources.list&lt;br /&gt;Secondly update your current system:&lt;br /&gt;sudo aptitude update&lt;br /&gt;sudo aptitude safe-upgrade&lt;br /&gt;MySQL&lt;br /&gt;First we'll install MySQL&lt;br /&gt;sudo aptitude install mysql-client mysql-server&lt;br /&gt;This will prompt you for a root password. Choose someting wise and remember it! For purpose of this tutorial I will set it to rootPASSWORD&lt;br /&gt;Postfix&lt;br /&gt;Then we'll install postfix&lt;br /&gt;sudo aptitude install postfix postfix-mysql&lt;br /&gt;This will prompt you to choose type of email server. Select internet site It will also suggest a server name. Correct this if needed.&lt;br /&gt;SASL&lt;br /&gt;sudo aptitude install libsasl2-modules libsasl2-modules-sql libgsasl7\&lt;br /&gt;    libauthen-sasl-cyrus-perl sasl2-bin libpam-mysql&lt;br /&gt;ClamAV&lt;br /&gt;sudo aptitude install clamav-base libclamav6 clamav-daemon clamav-freshclam&lt;br /&gt;(Earlier vesions of Ubuntu may use libclamav5)&lt;br /&gt;Amavis, SpamAssassin, postgrey&lt;br /&gt;sudo aptitude install amavisd-new&lt;br /&gt;sudo aptitude install spamassassin spamc&lt;br /&gt;sudo aptitude install postgrey&lt;br /&gt;SquirrelMail&lt;br /&gt;sudo aptitude install squirrelmail squirrelmail-locales php-pear php5-cli&lt;br /&gt;phpMyAdmin&lt;br /&gt;sudo aptitude install phpmyadmin&lt;br /&gt;Enter Yes to set it up, enter root mysql password, enter a phpmyadmin mysql user password twice. Accept apache2 as the web server.&lt;br /&gt;ShoreWall&lt;br /&gt;sudo aptitude install shorewall-common shorewall-perl shorewall-doc&lt;br /&gt;# for earlier ubuntu versions use package shorewall instead&lt;br /&gt;Amazon provides a firewall/ access control for its servers, so not always needed then, but nice to have. And in all others situations; a must have.&lt;br /&gt;Courier&lt;br /&gt;sudo aptitude install courier-base courier-authdaemon courier-authlib-mysql \ &lt;br /&gt;   courier-imap courier-imap-ssl courier-ssl&lt;br /&gt;will prompt you about webdirectories. You can say no to this. It will also warn you about the certificate location. Ignore it.&lt;br /&gt;Extras&lt;br /&gt;I also install a few other packages that I personally prefer. But nothing todo with the mail server.&lt;br /&gt;sudo aptitude install vim mutt lynx&lt;br /&gt;Package status&lt;br /&gt;To find out which packages you may have installed, you can use for example:&lt;br /&gt;sudo dpkg --list | grep postfix&lt;br /&gt;or&lt;br /&gt;sudo aptitude search postfix&lt;br /&gt;EC2 Bundle&lt;br /&gt;My AMI flurdy-amis/ubuntu-mail-server-clean is based on Canonical's official Ubuntu with these basic mail server packages installed.&lt;br /&gt;Return to top.&lt;br /&gt;Configuration&lt;br /&gt;Core/Simple&lt;br /&gt;Firewall (Shorewall)&lt;br /&gt;MTA (Postfix)&lt;br /&gt;Database (MySQL)&lt;br /&gt;Pop/IMAP (Courier)&lt;br /&gt;Advanced&lt;br /&gt;Content Checks (amivisd-new)&lt;br /&gt;Anti-Spam(SpamAssassin)&lt;br /&gt;Anti-Virus (ClamAV)&lt;br /&gt;Policy Check (PostGrey)&lt;br /&gt;Secure&lt;br /&gt;Authentication (SASL)&lt;br /&gt;Encryption (TLS)&lt;br /&gt;Webmail (SquirrelMail)&lt;br /&gt;Administration (phpMyAdmin)&lt;br /&gt;Simple mail server&lt;br /&gt;Now lets configure a simple mail server using some of the packages installed.&lt;br /&gt;Firewall&lt;br /&gt;Shorewall&lt;br /&gt;Not essential for an EC2 image. It is essential for a normal server. UFW is bundled with recent Ubuntu distributions, but I still prefer Shorewall for servers.&lt;br /&gt;Basically at first you want to only allow SSH. Then SMTP and IMAP from your IP only.&lt;br /&gt;When you are confident that the mail server is secure, you can open SMTP to the world. If you prefer you can also open IMAP to the world, unless you have a very small client IP range.&lt;br /&gt;Later you may open web access to the webmail and admin gui. This you may also restrict to specific IPs.&lt;br /&gt;SSH only&lt;br /&gt;By default Shorewall in Ubuntu has an empty set up. You can find the default values for Shorewall in /usr/share/doc/shorwall-common/default-config. And examples in /usr/share/doc/shorwall-common/examples. We will create a basic set up.&lt;br /&gt;First configure which network adapters we are accessing the net.&lt;br /&gt;cp /usr/share/doc/shorewall-common/default-config/interfaces /etc/shorewall/&lt;br /&gt;vi /etc/shorewall/interfaces&lt;br /&gt;net     eth0            detect          dhcp,tcpflags,logmartians,nosmurfs&lt;br /&gt;Then we will configure network zones&lt;br /&gt;cp /usr/share/doc/shorewall-common/default-config/zones /etc/shorewall/&lt;br /&gt;vi /etc/shorewall/zones&lt;br /&gt;Add the firewall if not there and the internet as a zone.&lt;br /&gt;fw firewall&lt;br /&gt;# loc  ipv4  &lt;br /&gt;net     ipv4&lt;br /&gt;Then if needed to specify hosts you can do it in this file. E.g. If you wanto specify what is your home IP etc.&lt;br /&gt;cp /usr/share/doc/shorewall-common/default-config/hosts /etc/shorewall/&lt;br /&gt;vi /etc/shorewall/hosts&lt;br /&gt;# loc eth0:192.168.0.0/24&lt;br /&gt;Then set what is the default policy for firewall access.&lt;br /&gt;cp /usr/share/doc/shorewall-common/default-config/policy /etc/shorewall/&lt;br /&gt;vi /etc/shorewall/policy&lt;br /&gt;$FW             net             ACCEPT&lt;br /&gt;net             $FW             DROP            info&lt;br /&gt;net             all             DROP            info&lt;br /&gt;# The FOLLOWING POLICY MUST BE LAST&lt;br /&gt;all             all             REJECT          info&lt;br /&gt;For safety in case it goes down.&lt;br /&gt;cp /usr/share/doc/shorewall-common/default-config/routestopped /etc/shorewall/&lt;br /&gt;vi /etc/shorewall/routestopped&lt;br /&gt;eth0            0.0.0.0                 routeback&lt;br /&gt;You may put in a netmask of your ip range if you are more concerned.&lt;br /&gt;Now for the main firewall rules. You can find predetermined macro rules for Shorewall in /usr/share/shorewall.&lt;br /&gt;cp /usr/share/doc/shorewall-common/default-config/rules /etc/shorewall/&lt;br /&gt;vi /etc/shorewall/rules&lt;br /&gt;SSH/ACCEPT      net             $FW&lt;br /&gt;Open for business&lt;br /&gt;Once your server is working come back to this step and open up SMTP and Web access to others.&lt;br /&gt;vi /etc/shorewall/rules&lt;br /&gt;Ping/ACCEPT     net             $FW&lt;br /&gt;&lt;br /&gt;# Permit all ICMP traffic FROM the firewall TO the net zone&lt;br /&gt;ACCEPT          $FW             net             icmp&lt;br /&gt;&lt;br /&gt;# mail lines&lt;br /&gt;SMTP/ACCEPT     net             $FW&lt;br /&gt;SMTPS/ACCEPT    net             $FW&lt;br /&gt;Submission/ACCEPT       net             $FW&lt;br /&gt;IMAP/ACCEPT     net             $FW&lt;br /&gt;IMAPS/ACCEPT    net             $FW&lt;br /&gt;&lt;br /&gt;#web&lt;br /&gt;Web/ACCEPT      net             $FW&lt;br /&gt;Firewall configuring is always risky business, as it is easy to lock yourself out. To test the setup syntax, run&lt;br /&gt;shorewall check&lt;br /&gt;Restart it with&lt;br /&gt;/etc/init.d/shorewall restart&lt;br /&gt;Then to switch it on during boot:&lt;br /&gt;vi /etc/default/shorewall&lt;br /&gt;startup=1&lt;br /&gt;For more details on IP Tables and Shorewall, look up its website.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;MTA&lt;br /&gt;Postfix&lt;br /&gt;You should put the name of your server in this file&lt;br /&gt;sudo vi /etc/mailname&lt;br /&gt;Could be something like smtp.domain.name, where domain name obviously is replaced with your domain name.&lt;br /&gt;Now will open the main postfix configuration file:&lt;br /&gt;sudo vi /etc/postfix/main.cf&lt;br /&gt;Debian and Ubuntu already puts in some sensible default values in this file. You may need to comment some of them out if we put the same in as well.&lt;br /&gt;First specify the name of your server.&lt;br /&gt;# This is already done in /etc/mailname&lt;br /&gt;#myhostname= mail.example.com&lt;br /&gt;Next is the origin which is the domain appended to email from this machine, this can be your full servername, or domain name.&lt;br /&gt;# myorigin=/etc/mailname&lt;br /&gt;myorigin=example.com&lt;br /&gt;Then decide what the greeting text will be. Enough info so it is useful, but not divelge everything to potential hackers.&lt;br /&gt;smtpd_banner = $myhostname ESMTP $mail_name&lt;br /&gt;Next you need to decide whether to send all outgoing mail via another SMTP server, or send them yourself. I send via my ISP's server, so it has to worry about the queing etc. If you send it yourself then you are not reliant on 3rd party server. But you may risk more exposure and accidentally be blocked by spam blockers. And it is more work for your server. Also many servers block dynamic dns hosts, so you may find your server gets rejected. However choose whichever you are comfortable with.&lt;br /&gt;# leave blank to do it yourself&lt;br /&gt;relayhost =&lt;br /&gt;# or put it an accessible smtp server&lt;br /&gt;relayhost = smtp.yourisp.com&lt;br /&gt;Next is network details. You will accept connection from anywhere, and you only trust this machine&lt;br /&gt;inet_interfaces = all&lt;br /&gt;mynetworks_style = host&lt;br /&gt;Next you can masquerade some outgoing addresses. Say your machine's name is mail.domain.com. You may not want outgoing mail to come from username@mail.example.com, as you'd prefer username@example.com. You can also state which domain not to masquerade. E.g. if you use a dynamic dns service, then your server address will be a subdomain. You can also specify which users not to masquerade.&lt;br /&gt;# masquerade_domains = mail.example.com www.example.com !sub.dyndomain.com&lt;br /&gt;# masquerade_exceptions = root&lt;br /&gt;As we will be using virtual domains, these need to be empty.&lt;br /&gt;local_recipient_maps = &lt;br /&gt;mydestination =&lt;br /&gt;Then will set a few numbers.&lt;br /&gt;# how long if undelivered before sending warning update to sender  &lt;br /&gt;delay_warning_time = 4h &lt;br /&gt;# will it be a permanent error or temporary&lt;br /&gt;unknown_local_recipient_reject_code = 450 &lt;br /&gt;# how long to keep message on queue before return as failed.&lt;br /&gt;# some have 3 days, I have 16 days as I am backup server for some people&lt;br /&gt;# whom go on holiday with their server switched off.&lt;br /&gt;maximal_queue_lifetime = 7d &lt;br /&gt;# max and min time in seconds between retries if connection failed&lt;br /&gt;minimal_backoff_time = 1000s &lt;br /&gt;maximal_backoff_time = 8000s &lt;br /&gt;# how long to wait when servers connect before receiving rest of data&lt;br /&gt;smtp_helo_timeout = 60s &lt;br /&gt;# how many address can be used in one message.&lt;br /&gt;# effective stopper to mass spammers, accidental copy in whole address list&lt;br /&gt;# but may restrict intentional mail shots.&lt;br /&gt;smtpd_recipient_limit = 16 &lt;br /&gt;# how many error before back off.&lt;br /&gt;smtpd_soft_error_limit = 3 &lt;br /&gt;# how many max errors before blocking it.&lt;br /&gt;smtpd_hard_error_limit = 12&lt;br /&gt;Now we can specify some restrictions. Be carefull that each setting is on one line only.&lt;br /&gt;# Requirements for the HELO statement&lt;br /&gt;smtpd_helo_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_hostname, &lt;br /&gt;  reject_invalid_hostname, permit&lt;br /&gt;# Requirements for the sender details&lt;br /&gt;smtpd_sender_restrictions = permit_mynetworks, warn_if_reject reject_non_fqdn_sender, &lt;br /&gt;  reject_unknown_sender_domain, reject_unauth_pipelining, permit&lt;br /&gt;# Requirements for the connecting server &lt;br /&gt;smtpd_client_restrictions = reject_rbl_client sbl.spamhaus.org, &lt;br /&gt;  reject_rbl_client blackholes.easynet.nl, &lt;br /&gt;  reject_rbl_client dnsbl.njabl.org &lt;br /&gt;# Requirement for the recipient address&lt;br /&gt;smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, &lt;br /&gt;  reject_non_fqdn_recipient, reject_unknown_recipient_domain, &lt;br /&gt;  reject_unauth_destination, permit&lt;br /&gt;smtpd_data_restrictions = reject_unauth_pipelining&lt;br /&gt;Further restrictions:&lt;br /&gt;# require proper helo at connections &lt;br /&gt;smtpd_helo_required = yes&lt;br /&gt;# waste spammers time before rejecting them&lt;br /&gt;smtpd_delay_reject = yes&lt;br /&gt;disable_vrfy_command = yes&lt;br /&gt;Next we need to set some maps and lookups for the virtual domains.&lt;br /&gt;# not sure of the difference of the next two&lt;br /&gt;# but they are needed for local aliasing&lt;br /&gt;alias_maps = hash:/etc/postfix/aliases&lt;br /&gt;alias_database = hash:/etc/postfix/aliases&lt;br /&gt;# this specifies where the virtual mailbox folders will be located&lt;br /&gt;virtual_mailbox_base = /var/spool/mail/virtual&lt;br /&gt;# this is for the mailbox location for each user&lt;br /&gt;virtual_mailbox_maps = mysql:/etc/postfix/mysql_mailbox.cf&lt;br /&gt;# and this is for aliases&lt;br /&gt;virtual_alias_maps = mysql:/etc/postfix/mysql_alias.cf&lt;br /&gt;# and this is for domain lookups&lt;br /&gt;virtual_mailbox_domains = mysql:/etc/postfix/mysql_domains.cf&lt;br /&gt;# this is how to connect to the domains (all virtual, but the option is there)&lt;br /&gt;# not used yet&lt;br /&gt;# transport_maps = mysql:/etc/postfix/mysql_transport.cf&lt;br /&gt;You can (as in my older editions) use a lookup for the uid and gid of the owner of mail files. But I tend to have one owner(virtual), so instead add this:&lt;br /&gt;virtual_uid_maps = static:5000&lt;br /&gt;virtual_gid_maps = static:5000&lt;br /&gt;You need to set up an alias file. This is only used locally, and not by your own mail domains.&lt;br /&gt;sudo cp /etc/aliases /etc/postfix/aliases&lt;br /&gt;# may want to view the file to check if ok.&lt;br /&gt;# especially that the final alias, eg root goes&lt;br /&gt;# to a real person&lt;br /&gt;sudo postalias /etc/postfix/aliases&lt;br /&gt;Next you need to set up the folder where the virtual mail will be stored. This may have already been done by the apt-get. And also create the user whom will own the folders.&lt;br /&gt;# to add if there is not a virtual user&lt;br /&gt;sudo mkdir /var/spool/mail/virtual&lt;br /&gt;sudo groupadd --system virtual -g 5000&lt;br /&gt;sudo useradd --system virtual -u 5000 -g 5000&lt;br /&gt;sudo chown -R virtual:virtual /var/spool/mail/virtual&lt;br /&gt;Note: If using Amazon ec2 you may want to move the mail spool to /mnt or an EBS location. You will need to symlink correctly afterwards.&lt;br /&gt;Return to top.&lt;br /&gt;Postfix's MySQL configuration&lt;br /&gt;Next we need to set up the files to access the lookups via the database. We will only set up a few now, and the rest later when/if needed:&lt;br /&gt;Edit(create) how to find the users mailbox location&lt;br /&gt;sudo vi /etc/postfix/mysql_mailbox.cf&lt;br /&gt;user=mail&lt;br /&gt;password=mailPASSWORD&lt;br /&gt;dbname=maildb&lt;br /&gt;table=users&lt;br /&gt;select_field=maildir&lt;br /&gt;where_field=id&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;Create how to find the email alias:&lt;br /&gt;sudo vi /etc/postfix/mysql_alias.cf&lt;br /&gt;user=mail&lt;br /&gt;password=mailPASSWORD&lt;br /&gt;dbname=maildb&lt;br /&gt;table=aliases&lt;br /&gt;select_field=destination&lt;br /&gt;where_field=mail&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;Create how to find the domains:&lt;br /&gt;sudo vi /etc/postfix/mysql_domains.cf&lt;br /&gt;user=mail&lt;br /&gt;password=mailPASSWORD&lt;br /&gt;dbname=maildb&lt;br /&gt;table=domains&lt;br /&gt;select_field=domain&lt;br /&gt;where_field=domain&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;If you specify an ip in hosts, (as opposed to 'localhost') then it will communicate over tcp and not the mysql socket. (chroot restriction). Ps. remember to replace the passwords with your chosen mail user password.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Database&lt;br /&gt;MySQL&lt;br /&gt;Now we will need to create the tables for thos lookups just specified. First you need to create a user to use in MySQL for mail only. Then you need to create the database, Take note of your chosen mail username and password. You will need the password you specified for root during MySQL package installation.&lt;br /&gt;# If not already done (in package installation)...&lt;br /&gt;mysqladmin -u root password new_password&lt;br /&gt;# log in as root&lt;br /&gt;mysql -u root -p&lt;br /&gt;# then enter password for the root account when prompted&lt;br /&gt;Enter password:&lt;br /&gt;# then we create the mail database&lt;br /&gt;create database maildb;&lt;br /&gt;# then we create a new user: "mail"&lt;br /&gt;GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP&lt;br /&gt;ON maildb.* TO 'mail'@'localhost' IDENTIFIED by 'mailPASSWORD';&lt;br /&gt;GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP&lt;br /&gt;ON maildb.* TO 'mail'@'%' IDENTIFIED by 'mailPASSWORD';&lt;br /&gt;exit;&lt;br /&gt;Obviously replace mailPASSWORD with your chosen password!&lt;br /&gt;Then you will need to create these tables:&lt;br /&gt;aliases&lt;br /&gt;domains&lt;br /&gt;users&lt;br /&gt;We will create more later on for further extensions, but only these are relevant now.&lt;br /&gt;Log in to mysql as the new mail user&lt;br /&gt;mysql -u mail -p maildb &lt;br /&gt;# enter the newly created password&lt;br /&gt;Enter password:&lt;br /&gt;Then run this commands to create the tables:&lt;br /&gt;CREATE TABLE `aliases` (&lt;br /&gt;`pkid` smallint(3) NOT NULL auto_increment,&lt;br /&gt;`mail` varchar(120) NOT NULL default '',&lt;br /&gt;`destination` varchar(120) NOT NULL default '',&lt;br /&gt;`enabled` tinyint(1) NOT NULL default '1',&lt;br /&gt;PRIMARY KEY  (`pkid`),&lt;br /&gt;UNIQUE KEY `mail` (`mail`)&lt;br /&gt;) ;&lt;br /&gt;CREATE TABLE `domains` (&lt;br /&gt;`pkid` smallint(6) NOT NULL auto_increment,&lt;br /&gt;`domain` varchar(120) NOT NULL default '',&lt;br /&gt;`transport` varchar(120) NOT NULL default 'virtual:',&lt;br /&gt;`enabled` tinyint(1) NOT NULL default '1',&lt;br /&gt;PRIMARY KEY  (`pkid`)&lt;br /&gt;) ;&lt;br /&gt;CREATE TABLE `users` (&lt;br /&gt;`id` varchar(128) NOT NULL default '',&lt;br /&gt;`name` varchar(128) NOT NULL default '',&lt;br /&gt;`uid` smallint(5) unsigned NOT NULL default '5000',&lt;br /&gt;`gid` smallint(5) unsigned NOT NULL default '5000',&lt;br /&gt;`home` varchar(255) NOT NULL default '/var/spool/mail/virtual',&lt;br /&gt;`maildir` varchar(255) NOT NULL default 'blah/',&lt;br /&gt;`enabled` tinyint(3) unsigned NOT NULL default '1',&lt;br /&gt;`change_password` tinyint(3) unsigned NOT NULL default '1',&lt;br /&gt;`clear` varchar(128) NOT NULL default 'ChangeMe',&lt;br /&gt;`crypt` varchar(128) NOT NULL default 'sdtrusfX0Jj66',&lt;br /&gt;`quota` varchar(255) NOT NULL default '',&lt;br /&gt;`procmailrc` varchar(128) NOT NULL default '',&lt;br /&gt;`spamassassinrc` varchar(128) NOT NULL default '',&lt;br /&gt;PRIMARY KEY  (`id`),&lt;br /&gt;UNIQUE KEY `id` (`id`)&lt;br /&gt;) ;&lt;br /&gt;The last few fields in the users table are not required, but useful if you extend later.&lt;br /&gt;# To visualise the tables created:&lt;br /&gt;describe aliases; describe domains; describe users; &lt;br /&gt;# then quit mysql&lt;br /&gt;exit;&lt;br /&gt;Next is to edit the MySQL's my.cnf file. In Ubuntu/debian this is created by default. In Mandrake I had to manually create a blank one in /etc. But we need to configure it, so:&lt;br /&gt;sudo vi /etc/mysql/my.cnf&lt;br /&gt;In previous version you needed to comment out this line&lt;br /&gt;#skip-networking&lt;br /&gt;However in todays file the default is to bind the address to localhost, which is fine.&lt;br /&gt;bind-address = 127.0.0.1&lt;br /&gt;It is very useful at the start to log any SQL calls that makes it to MySQL. So enable these lines:&lt;br /&gt;general_log_file = /var/log/mysql/mysql.log&lt;br /&gt;general_log = 1&lt;br /&gt;Then in a few weeks comment it out when everything is working, as it slows mysql down&lt;br /&gt;Restart MySQL to make sure its picking up the new settings.&lt;br /&gt;sudo /etc/init.d/mysql restart&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Pop/IMAP&lt;br /&gt;Courier IMAP&lt;br /&gt;Please refer to previous edition for more explanations. But below is the details of what you need to change.&lt;br /&gt;sudo vi /etc/courier/authdaemonrc&lt;br /&gt;Change to mysql mode.&lt;br /&gt;authmodulelist="authmysql"&lt;br /&gt;Further down enable logging.&lt;br /&gt;DEBUG_LOGIN=2&lt;br /&gt;sudo vi /etc/courier/authmysqlrc&lt;br /&gt;Changed user&lt;br /&gt;MYSQL_USERNAME mail&lt;br /&gt;Changed password to whichever you have chosen&lt;br /&gt;MYSQL_PASSWORD mailPASSWORD&lt;br /&gt;Changed database&lt;br /&gt;MYSQL_DATABASE maildb&lt;br /&gt;Changed users table&lt;br /&gt;MYSQL_USER_TABLE users&lt;br /&gt;Keep commented in crypt pw&lt;br /&gt;MYSQL_CRYPT_PWFIELD crypt&lt;br /&gt;Keep commented out clear pw&lt;br /&gt;# MYSQL_CLEAR_PWFIELD clear&lt;br /&gt;Added maildir&lt;br /&gt;MYSQL_MAILDIR_FIELD concat(home,'/',maildir)&lt;br /&gt;Added where clause&lt;br /&gt;MYSQL_WHERE_CLAUSE enabled=1&lt;br /&gt;Lastly you can have a look at the imapd file, but no changes is needed.&lt;br /&gt;vi /etc/courier/imapd&lt;br /&gt;Return to top.&lt;br /&gt;Summary&lt;br /&gt;You now have a basic mail server!&lt;br /&gt;Before continuing to the advanced and secure mail server you must ensure the basic setup works. This will save you from loads of pain further on. &lt;br /&gt;It is very easy to make typos, miss tiny steps, unclear steps or simple actual errors in this howto.&lt;br /&gt;Insert stub data from data section&lt;br /&gt;Apply advice from test section judicously&lt;br /&gt;Ensure the mail server can receive email correctly first, then try sending.&lt;br /&gt;Once you are positive the mail has been received, the mail folders have been automatically created,&lt;br /&gt;only then you should test if you can actually read the emails before proceding&lt;br /&gt;Ive created an EC2 bundle for this stage: flurdy-amis/ubuntu-mail-server-simple.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Somewhere, something went terribly wrong&lt;br /&gt;Advanced mail server&lt;br /&gt;Now lets extend this setup with more useful content checks , security and user interfaces.&lt;br /&gt;Content Checks (Anti spam &amp; anti virus)&lt;br /&gt;Amavisd-new&lt;br /&gt;Amavisd ties together all the different ways of checking email content for spam and viruses.&lt;br /&gt;The defaults are pretty good and also the ubuntu documentation is pretty clear, and recommended.&lt;br /&gt;Here is a tweaked version of it:&lt;br /&gt;Initially we will not enable spam or virus detection! This is so we can get amavis set up to receive, check and pass on emails before we go on and over-complicate it.&lt;br /&gt;All of amavis' configuration files are in /etc/amavisd. They are now spread across several files in conf.d. Debian and Ubuntu defaults are now very sensible and spread into seperate files.&lt;br /&gt;cd /etc/amavis/conf.d&lt;br /&gt;01-debian defaults are fine.&lt;br /&gt;Have a look at&lt;br /&gt;less 05-domain_id&lt;br /&gt;but dont change anything in it.&lt;br /&gt;Have a look at&lt;br /&gt;less 05-node_id&lt;br /&gt;but dont change anything in it.&lt;br /&gt;Have a look at&lt;br /&gt;less 15-av_scanners&lt;br /&gt;but dont change anything in it.&lt;br /&gt;Edit content check file&lt;br /&gt;sudo vi 15-content_filter_mode&lt;br /&gt;Comment out both virus and spam scans. (Default).&lt;br /&gt;# #@bypass_virus_checks_maps = (&lt;br /&gt;#   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);&lt;br /&gt;# @bypass_spam_checks_maps = (&lt;br /&gt;#   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);&lt;br /&gt;Have a look at&lt;br /&gt;less 20-debian_defaults&lt;br /&gt;and&lt;br /&gt;less 21-ubuntu_defaults&lt;br /&gt;but dont change anything in them.&lt;br /&gt;25-amavis_helpers defaults are fine.&lt;br /&gt;30-template-localization defaults are fine.&lt;br /&gt;Edit user file&lt;br /&gt;sudo vi 50-user&lt;br /&gt;In the middle insert:&lt;br /&gt;@local_domains_acl = qw(.);&lt;br /&gt;$log_level = 2;&lt;br /&gt;$syslog_priority = 'debug';&lt;br /&gt;# $sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level&lt;br /&gt;# $sa_tag2_level_deflt = 6.31; # add 'spam detected' headers at that level&lt;br /&gt;$sa_kill_level_deflt = 8.0; # triggers spam evasive actions&lt;br /&gt;# $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent&lt;br /&gt;$final_spam_destiny = D_PASS;&lt;br /&gt;# $final_spam_destiny = D_REJECT; # default &lt;br /&gt;# $final_spam_destiny = D_BOUNCE; # debian default &lt;br /&gt;# $final_spam_destiny = D_DISCARD; # ubuntu default, recommended as sender is usually faked&lt;br /&gt;We have now setup amavis to scan and pass along incomming email. Next we will setup postfix to talk to amavis.&lt;br /&gt;vi /etc/postfix/master.cf&lt;br /&gt;Append these lines to the end of the file (make sure they are not already present). (Note the -o lines have spaces in front of them.&lt;br /&gt;amavis      unix    -       -       -       -       2       smtp&lt;br /&gt;        -o smtp_data_done_timeout=1200&lt;br /&gt;        -o smtp_send_xforward_command=yes&lt;br /&gt;        -o disable_dns_lookups=yes&lt;br /&gt;        -o max_use=20&lt;br /&gt;127.0.0.1:10025 inet    n       -       -       -       -       smtpd&lt;br /&gt;        -o content_filter=&lt;br /&gt;        -o local_recipient_maps=&lt;br /&gt;        -o relay_recipient_maps=&lt;br /&gt;        -o smtpd_restriction_classes=&lt;br /&gt;        -o smtpd_delay_reject=no&lt;br /&gt;        -o smtpd_client_restrictions=permit_mynetworks,reject&lt;br /&gt;        -o smtpd_helo_restrictions=&lt;br /&gt;        -o smtpd_sender_restrictions=&lt;br /&gt;        -o smtpd_recipient_restrictions=permit_mynetworks,reject&lt;br /&gt;        -o smtpd_data_restrictions=reject_unauth_pipelining&lt;br /&gt;        -o smtpd_end_of_data_restrictions=&lt;br /&gt;        -o mynetworks=127.0.0.0/8&lt;br /&gt;        -o smtpd_error_sleep_time=0&lt;br /&gt;        -o smtpd_soft_error_limit=1001&lt;br /&gt;        -o smtpd_hard_error_limit=1000&lt;br /&gt;        -o smtpd_client_connection_count_limit=0&lt;br /&gt;        -o smtpd_client_connection_rate_limit=0&lt;br /&gt;        -o receive_override_options=no_header_body_checks,no_unknown_recipient_checks&lt;br /&gt;Also add the following two lines immediately below the "pickup" transport service:&lt;br /&gt; -o content_filter=&lt;br /&gt;        -o receive_override_options=no_header_body_checks&lt;br /&gt;and then added to main.cf&lt;br /&gt;sudo vi /etc/postfix/main.cf&lt;br /&gt;content_filter = amavis:[127.0.0.1]:10024&lt;br /&gt;Enable scanning by ClamAV of amavis' temporary files.&lt;br /&gt;sudo adduser clamav amavis&lt;br /&gt;This should be it to get amavis working. If emails are picked up by amavis and passed back to postfix then it looks okay. Only when finished testing do you proced to uncomment the anti virus and anti spam lines in&lt;br /&gt;sudo vi 15-content_filter_mode&lt;br /&gt;@bypass_virus_checks_maps = (&lt;br /&gt;   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);&lt;br /&gt;@bypass_spam_checks_maps = (&lt;br /&gt;   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);&lt;br /&gt;But do that after the next section (SpamAssassin).&lt;br /&gt;When things are working we will turn down logging level, and start bouncing/discarding spam.&lt;br /&gt;sudo vi /etc/amavis/conf.d/50-user&lt;br /&gt;@local_domains_acl = qw(.);&lt;br /&gt;$log_level = 1;&lt;br /&gt;$syslog_priority = 'info';&lt;br /&gt;# $sa_tag_level_deflt = 2.0; # add spam info headers if at, or above that level&lt;br /&gt;# $sa_tag2_level_deflt = 6.31; # add 'spam detected' headers at that level&lt;br /&gt;$sa_kill_level_deflt = 8.0; # triggers spam evasive actions&lt;br /&gt;# $sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent&lt;br /&gt;# $final_spam_destiny = D_PASS;&lt;br /&gt;# $final_spam_destiny = D_REJECT; # default &lt;br /&gt;# $final_spam_destiny = D_BOUNCE; # debian default &lt;br /&gt;$final_spam_destiny = D_DISCARD; # ubuntu default, recommended as sender is usually faked&lt;br /&gt;Return to top.&lt;br /&gt;Anti-Spam&lt;br /&gt;SpamAssassin&lt;br /&gt;The default config of spam assassin is okay. You could refer to previous edition for more configuration options.&lt;br /&gt;You do need to tell SpamAssassin to start smapd on boot.&lt;br /&gt;vi /etc/default/spamassassin&lt;br /&gt;ENABLED=1&lt;br /&gt;One configuration option you could tweak is to enable Bayes and auto learning.&lt;br /&gt;vi /etc/spamassassin/local.cf&lt;br /&gt;&lt;br /&gt;I read your email&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Anti Virus&lt;br /&gt;ClamAV&lt;br /&gt;ClamAV does not need setting up. Configuration files are in /etc/clamav, but they are automatically generated, so do not edit.&lt;br /&gt;By default freshclam, the daemon that updates the virus definition database, is run 24 times a day. That seems a little excessive, so I tend to set that to once a day.&lt;br /&gt;sudo dpkg-reconfigure clamav-freshclam&lt;br /&gt;It will also ask if you want it to be daemon (yes) and which server is closest to you.&lt;br /&gt;If needed, the command below will redefine the configuration with a lot of questions. Not needed unless you need to configure.&lt;br /&gt;sudo dpkg-reconfigure clamav-base&lt;br /&gt;Return to top.&lt;br /&gt;Postgrey&lt;br /&gt;The default config of postgrey is okay. However you need to tell Postfix to use it.&lt;br /&gt;sudo vi /etc/postfix/main.cf&lt;br /&gt;And then edit the recipient restrictions:&lt;br /&gt;smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, permit_sasl_authenticated,&lt;br /&gt;  reject_non_fqdn_recipient, reject_unknown_recipient_domain, reject_unauth_destination, &lt;br /&gt;  check_policy_service inet:127.0.0.1:10023, permit&lt;br /&gt;You can tweak whitelisting in /etc/postgrey. You can tweak postgrey configuration by tweaking /etc/default/postgrey. E.g. delay, auto whitelisting, or reject message.&lt;br /&gt;POSTGREY_OPTS="--inet=10023 --max-age=365"&lt;br /&gt;Return to top.&lt;br /&gt;You know have an advanced mail server. You can use this, but Id recommend continuing. However this is a good point to test the set up so far and to insert some data in the db.&lt;br /&gt;Ive created an EC2 bundle for this stage: flurdy-amis/ubuntu-mail-server-spam.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;No, I will not fix your computer&lt;br /&gt;Secure mail server&lt;br /&gt;Stopping hackers, phishers, spammers, your boss and your neighbour from accessing your server or the traffic in between is important, and easily done.&lt;br /&gt;Authentication&lt;br /&gt;Normal email traffic between clients and servers are in open plain text. That includes passwords and content of emails.&lt;br /&gt;SASL&lt;br /&gt;SASL secures the actual authentication (login), by encoding the passwords so that it can not be easily intercepted. The rest of the emails are however in clear plain text.&lt;br /&gt;SASL can be a royal pain to set up, especially as it does not support storing encrypted passwords by default in Ubuntu. &lt;br /&gt;Therefor my previous editions described how to configure SASL using plain text passwords in the database.&lt;br /&gt;Obviously this is not ideal, so there are ways to combine SASL and storing encrypted passwords. In the future the packages that comes with Ubuntu may support the password_format configuration option for SASL. But until then you can configure SASL to ask PAM to compare the passwords:&lt;br /&gt;Install packages if not all installed already:&lt;br /&gt;sudo aptitude install sasl2-bin libpam-mysql libsasl2-modules libsasl2-modules-sql&lt;br /&gt;Enable postfix to access SASL files:&lt;br /&gt;sudo adduser postfix sasl&lt;br /&gt;Create sasl files accessibly even by chrooted Postfix:&lt;br /&gt;sudo mkdir -p /var/spool/postfix/var/run/saslauthd&lt;br /&gt;Add SASL configurations to Postfix:&lt;br /&gt;sudo vi /etc/postfix/main.cf&lt;br /&gt;# SASL&lt;br /&gt;smtpd_sasl_auth_enable = yes&lt;br /&gt;# If your potential clients use Outlook Express or other older clients&lt;br /&gt;# this needs to be set to yes&lt;br /&gt;broken_sasl_auth_clients = no&lt;br /&gt;smtpd_sasl_security_options = noanonymous&lt;br /&gt;smtpd_sasl_local_domain =&lt;br /&gt;Modify these existing configurations:&lt;br /&gt;# Add permit_sasl_authenticated to you existing  smtpd_sender_restrictions&lt;br /&gt;smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks, &lt;br /&gt;  warn_if_reject reject_non_fqdn_sender, reject_unknown_sender_domain,&lt;br /&gt;  reject_unauth_pipelining, permit&lt;br /&gt;# Add permit_sasl_authenticated to you existing  smtpd_recipient_restrictions&lt;br /&gt;smtpd_recipient_restrictions = reject_unauth_pipelining, permit_mynetworks, &lt;br /&gt;  permit_sasl_authenticated, reject_non_fqdn_recipient, reject_unknown_recipient_domain, &lt;br /&gt;  reject_unauth_destination, check_policy_service inet:127.0.0.1:10023, permit&lt;br /&gt;Change how SASLAUTHD is run:&lt;br /&gt;sudo vi /etc/default/saslauthd&lt;br /&gt;# Toggle this to yes&lt;br /&gt;START=yes&lt;br /&gt;# Switch this to be under postfix's spool&lt;br /&gt;# And add -r so that the realm(domain) is part of the username&lt;br /&gt;OPTIONS="-r -c -m /var/spool/postfix/var/run/saslauthd"&lt;br /&gt;Tell postfix how to interact with SASL:&lt;br /&gt;sudo vi /etc/postfix/sasl/smtpd.conf&lt;br /&gt;pwcheck_method: saslauthd&lt;br /&gt;mech_list: plain login cram-md5 digest-md5&lt;br /&gt;log_level: 7&lt;br /&gt;allow_plaintext: true&lt;br /&gt;auxprop_plugin: mysql&lt;br /&gt;sql_engine: mysql&lt;br /&gt;sql_hostnames: 127.0.0.1&lt;br /&gt;sql_user: mail&lt;br /&gt;sql_passw: mailPASSWORD&lt;br /&gt;sql_database: maildb&lt;br /&gt;sql_select: select crypt from users where id='%u@%r' and enabled = 1&lt;br /&gt;(When SASL is working you can remove the log_level line.)&lt;br /&gt;Tell the pam how to to authenticate smtp via mysql:&lt;br /&gt;sudo vi /etc/pam.d/smtp&lt;br /&gt;These must be on 2 lines only, but I have broken them up for easier to read.&lt;br /&gt;auth required pam_mysql.so user=mail passwd=aPASSWORD &lt;br /&gt;   host=127.0.0.1 db=maildb table=users usercolumn=id passwdcolumn=crypt crypt=1&lt;br /&gt;account sufficient pam_mysql.so user=mail passwd=aPASSWORD &lt;br /&gt;   host=127.0.0.1 db=maildb table=users usercolumn=id passwdcolumn=crypt crypt=1&lt;br /&gt;In addition to tailing var/log/mail.log and /var/log/mysql/mysql.log it is quite usefull to tail the auth.log as well when testing SASL.&lt;br /&gt;tail -f /var/log/auth.log&lt;br /&gt;Restart postfix and saslauthd to enable SASL for sending emails.&lt;br /&gt;sudo /etc/init.d/saslauthd restart&lt;br /&gt;sudo /etc/init.d/postfix restart&lt;br /&gt;Imap SASL / Courier&lt;br /&gt;I tend not to have SASL for my courier authentication, as I enforce TLS for all my clients. &lt;br /&gt;However if you have a more lenient access policy which is wise if you have many users, then you may want SASL in Courier as well:&lt;br /&gt;sudo vi /etc/courier/imapd&lt;br /&gt;This may already be avaiable as a commented out line. If not replace the current line by adding UTH=CRAM-MD5 AUTH=CRAM-SHA1 so it resembles something like this: (Again on one line)&lt;br /&gt;IMAP_CAPABILITY="IMAP4rev1 UIDPLUS CHILDREN NAMESPACE &lt;br /&gt;   THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=CRAM-MD5 AUTH=CRAM-SHA1 IDLE"&lt;br /&gt;sudo /etc/init.d/courier-authdaemon restart;&lt;br /&gt;sudo /etc/init.d/courier-imap restart&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Encryption&lt;br /&gt;TLS&lt;br /&gt;Encrypting the traffic stops anyone else listening in on your email communications. And is very recommended. There are different types of communication to encrypt: The data traffic between your email applications and the server when you read emails or when you send emails, and communication between other email servers and your server.&lt;br /&gt;For the encryption of reading emails, it is Courier you need to configure. For sending, and beetwen server encryption it is Postfix.&lt;br /&gt;TLS in Postfix&lt;br /&gt;To encrypt you need certificates. Ubuntu creates some for you for which you can use while setting up the server. However before you go live, it is recommended to create your own with your proper domain name etc. Please refer to previous edition for more detail.&lt;br /&gt;vi /etc/postfix/main.cf&lt;br /&gt;There are already some TLS settings in the default debian/ubuntu version of this file. I moved these to the end, for clarity, but that is up to you.&lt;br /&gt;# TLS parameters&lt;br /&gt;# smtp_use_tls = no&lt;br /&gt;smtp_tls_security_level = may&lt;br /&gt;# smtpd_use_tls=yes&lt;br /&gt;smtpd_tls_security_level = may&lt;br /&gt;# smtpd_tls_auth_only = no&lt;br /&gt;smtp_tls_note_starttls_offer = yes&lt;br /&gt;smtpd_tls_loglevel = 1&lt;br /&gt;smtpd_tls_received_header = yes&lt;br /&gt;smtpd_tls_session_cache_timeout = 3600s&lt;br /&gt;tls_random_source = dev:/dev/urandom&lt;br /&gt;smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem&lt;br /&gt;smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key&lt;br /&gt;# smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache&lt;br /&gt;# smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache&lt;br /&gt;smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt&lt;br /&gt;Next we have a look at the master.cf file.&lt;br /&gt;vi /etc/postfix/master.cf&lt;br /&gt;By default only the normal smtp service is enabled, which is fine. But I prefer to enable submission (port 587), so that clients can use it, and I can restrict them to TLS only. Also enabled smtps service (port 465), for some compatebility with some older clients (outlook express etc).&lt;br /&gt;submission inet n       -       n       -       -       smtpd&lt;br /&gt;  -o smtpd_sasl_auth_enable=yes&lt;br /&gt;# if you do not want to restrict it encryption only, comment out next line&lt;&lt;br /&gt;  -o smtpd_tls_auth_only=yes&lt;br /&gt;# -o smtpd_tls_security_level=encrypt&lt;br /&gt;#  -o header_checks=&lt;br /&gt;#  -o body_checks=&lt;&lt;br /&gt;  -o smtpd_client_restrictions=permit_sasl_authenticated,reject_unauth_destination,reject&lt;br /&gt;  -o smtpd_sasl_security_options=noanonymous,noplaintext&lt;br /&gt;  -o smtpd_sasl_tls_security_options=noanonymous&lt;br /&gt;# -o milter_macro_daemon_name=ORIGINATING&lt;&lt;br /&gt;smtps     inet  n       -       -       -       -       smtpd&lt;br /&gt;  -o smtpd_tls_wrappermode=yes&lt;br /&gt;  -o smtpd_sasl_auth_enable=yes &lt;br /&gt;  -o smtpd_tls_auth_only=yes&lt;br /&gt;  -o smtpd_client_restrictions=permit_sasl_authenticated,reject&lt;br /&gt;  -o smtpd_sasl_security_options=noanonymous,noplaintext&lt;br /&gt;  -o smtpd_sasl_tls_security_options=noanonymous&lt;br /&gt;#  -o milter_macro_daemon_name=ORIGINATING&lt;br /&gt;TLS in Courier&lt;br /&gt;Again Ubuntu has created a certificate for you, but if you want to create your own, especially for a properly named server, then do this.&lt;br /&gt;cd /etc/courier&lt;br /&gt;openssl req -x509 -newkey rsa:1024 -keyout imapd.pem \ &lt;br /&gt;  -out imapd.pem -nodes -days 999&lt;br /&gt;For more details review an earlier edition.&lt;br /&gt;Then you need to edit&lt;br /&gt;vi /etc/courier/imapd-ssl&lt;br /&gt;By default Ubuntu already points to you certificate&lt;br /&gt;TLS_CERTFILE=/etc/courier/imapd.pem&lt;br /&gt;Modify this if needed.&lt;br /&gt;Also you if want to restrict IMAP users to SSL/TLS only toggle this setting to 1.&lt;br /&gt;IMAP_TLS_REQUIRED=1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For maximum compatability it is not wise to restrict to TLS only for the traffic between servers. As this means not all valid emails sent by others can reach your server. However enabling them the option to encrypt is a good idea.&lt;br /&gt;Be aware that the emails are not encrypted on your machine, nor on the server. For this type of client encryption, please refer to previous edition for more on GnuPG.&lt;br /&gt;In some situations SASL and TLS do not play well together. Those situations are in combinations of storing encrypted passwords, using MD5 authentication over encrypted traffic. I recommend, insisting on TLS traffic with your authenticating clients, which then negates the need for SASL.&lt;br /&gt;You know have an advanced secure mail server. Now is another good point to test the set up so far and to insert some data in the db.&lt;br /&gt;Ive created an EC2 bundle for this stage: flurdy-amis/ubuntu-mail-server-secure.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Webmail&lt;br /&gt;Using among others the https://help.ubuntu.com/community/Squirrelmail as an updated reference.&lt;br /&gt;Alternative&lt;br /&gt;If you prefer the prettier Roundcube, but less powerfull (at the moment), the follow the Roundcube section in the extention section.&lt;br /&gt;Enable web access&lt;br /&gt;You may need to enable web access in the firewall. Check the firewall configuration if this neccessary.&lt;br /&gt;You need to copy a SquirrelMail configuration to apache.&lt;br /&gt;sudo cp /etc/squirrelmail/apache.conf /etc/apache2/sites-available/squirrelmail&lt;br /&gt;And enable with this:&lt;br /&gt;sudo ln -s /etc/apache2/sites-available/squirrelmail /etc/apache2/sites-enabled/500-squirrelmail&lt;br /&gt;Or as Florent recommends, use:&lt;br /&gt;sudo a2ensite squirrelmail&lt;br /&gt;You may accept the default apache configuration where squirrelmail is folder in all sites. But I prefer virtual hosting. But you dont need to do these next steps.&lt;br /&gt;sudo vi /etc/apache2/sites-available/squirrelmail&lt;br /&gt;Comment out the alias.&lt;br /&gt;# alias /squirrelmail /usr/share/squirrelmail&lt;br /&gt;Uncomment the virtual settings., and insert your servers name.&lt;br /&gt;# users will prefer a simple URL like http://webmail.example.com&lt;br /&gt;&lt;br /&gt;  DocumentRoot /usr/share/squirrelmail  &lt;br /&gt;  ServerName webmail.example.com&lt;br /&gt;If you have apache SSL enabled in apache, then you can also uncomment the mod_rewrite section for further security.&lt;br /&gt;Reload apache to activate changes. First test if ok.&lt;br /&gt;sudo apache2ctl -t&lt;br /&gt;Then reload it.&lt;br /&gt;sudo /etc/init.d/apache2 reload&lt;br /&gt;You can now go toyourdomain.com/squirrelmail/ or mail.yourdomain.com if you chose virtual host. This should show a squirrel mail page. Log in wont work yet though.&lt;br /&gt;Start configuring squirrel mail.&lt;br /&gt;sudo squirrelmail-configure&lt;br /&gt;Initially change nothing. You can customize more afterwards. You can browse, and exit sub menues by typing R.&lt;br /&gt;Type 2 to edit server settings. Type A to edit IMAP settings.&lt;br /&gt;Type 8 to edit server software. Enter courier.&lt;br /&gt;courier&lt;br /&gt;Now they say using TLS over localhost is a waste of time. But I do anyway. Type 7 to edit secure IMAP. Type&lt;br /&gt;Y&lt;br /&gt;to enable it.&lt;br /&gt;Type 5 to edit IMAP port. Enter&lt;br /&gt;993&lt;br /&gt;Type S to save your changes. Hit Enter.&lt;br /&gt;Type Q to exit.&lt;br /&gt;You can now go to yourdomain.com/squirrelmail/ or mail.yourdomain.com if you chose virtual host. This should show a squirrel mail page. Log in will now work. (Except you may not have defined users, check data section. And they may not have received an email which also means you can not view any IMAP info.)&lt;br /&gt;Please refer to previous edition for more detail. E.g. creating address books and user preferences.&lt;br /&gt;Return to top.&lt;br /&gt;Administration&lt;br /&gt;Enable web access&lt;br /&gt;You may need to enable web access in the firewall. Check the firewall configuration if this neccessary.&lt;br /&gt;You may choose to restrict phpMyAdmin to a spefic virtual host. If so you need to, edit&lt;br /&gt;sudo vi /etc/apache2/conf.d/phpmyadmin.conf&lt;br /&gt;and comment out the alias.&lt;br /&gt;#Alias /phpmyadmin /usr/share/phpmyadmin&lt;br /&gt;And insert the alias instead into a virtual host configuration in /etc/apache2/sites-available/. For this example we are not, and for testing we keep the Alias uncommented.&lt;br /&gt;Reload apache to activate changes. First test if ok.&lt;br /&gt;sudo apache2ctl -t&lt;br /&gt;Then reload it.&lt;br /&gt;sudo /etc/init.d/apache2 reload&lt;br /&gt;You can now go to http://yourdomain.com/phpmyadmin/, and login with the mail user. You can use it as it is, but I recommend securing it a bit more.&lt;br /&gt;One simple way is adding apache's .htaccess login requirement.&lt;br /&gt;Further restrictions can be restricting to a specific virtual host. Or renaming the folder. Purely ubfuscating, but simple.&lt;br /&gt;Or using the example in the webmail section, and adding SSL requirement to the connection. Or disabel mysql root's access via phpMyAdmin.&lt;br /&gt;Please refer to previous edition for example on htaccess, and mysql user restriction.&lt;br /&gt;You know have a finished mail server. This is as far as the main guide goes. Hope it was clear enough to follow.&lt;br /&gt;Now it is time to insert data, and to test how it works.&lt;br /&gt;Feel free to extend it with my suggestions further down.&lt;br /&gt;Ive created an EC2 bundle for this stage: flurdy-amis/ubuntu-mail-server-webmail.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Return to top.&lt;br /&gt;Data&lt;br /&gt;Add users and domains&lt;br /&gt;Required domains and users&lt;br /&gt;Example domains and users&lt;br /&gt;Adding template&lt;br /&gt;Common SQL&lt;br /&gt;Add users and domains&lt;br /&gt;So we got a fully set up mail server... Well no, there is no users, domains, no nothing!&lt;br /&gt;Okay, first you need add some default data, some which are required, some which make sense.&lt;br /&gt;Then we'll add your own users and domains.&lt;br /&gt;Required domains and users&lt;br /&gt;First the required domains for local mail&lt;br /&gt;# Use phpMyAdmin or command line mysql&lt;br /&gt;INSERT INTO domains (domain) VALUES&lt;br /&gt; ('localhost'),&lt;br /&gt; ('localhost.localdomain');&lt;br /&gt;Then some default aliases. Some people say these are not needed, but I'd include them.&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt; ('postmaster@localhost','root@localhost'),&lt;br /&gt; ('sysadmin@localhost','root@localhost'),&lt;br /&gt; ('webmaster@localhost','root@localhost'),&lt;br /&gt; ('abuse@localhost','root@localhost'),&lt;br /&gt; ('root@localhost','root@localhost'),&lt;br /&gt; ('@localhost','root@localhost'),&lt;br /&gt; ('@localhost.localdomain','@localhost');&lt;br /&gt;Then a root user.&lt;br /&gt;INSERT INTO users (id,name,maildir,crypt) VALUES &lt;br /&gt; ('root@localhost','root','root/', encrypt('apassword') );&lt;br /&gt;&lt;br /&gt;Domains and users&lt;br /&gt;Now lets add some proper data.&lt;br /&gt;Say you want this machine to handle data for the fictional domains of "blobber.org", "whopper.nu" and "lala.com".&lt;br /&gt;Then say this machine's name is "mail.blobber.org".&lt;br /&gt;All email to lala.com is to be forwarded to whupper.nu.&lt;br /&gt;INSERT INTO domains (domain) VALUES&lt;br /&gt; ('blobber.org'),&lt;br /&gt; ('mail.blobber.org'),&lt;br /&gt; ('whopper.nu'),&lt;br /&gt; ('lala.com');&lt;br /&gt;&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt; ('@lala.com','@whupper.nu'),&lt;br /&gt; ('@mail.blobber.org','@blobber.org'),&lt;br /&gt; ('postmaster@whopper.nu','postmaster@localhost'),&lt;br /&gt; ('abuse@whopper.nu','abuse@localhost'),&lt;br /&gt; ('postmaster@blobber.org','postmaster@localhost'),&lt;br /&gt; ('abuse@blobber.org','abuse@localhost');&lt;br /&gt;You also have two users called "Xandros" and "Vivita".&lt;br /&gt;INSERT INTO users (id,name,maildir,crypt) VALUES &lt;br /&gt; ('xandros@blobber.org','xandros','xandros/', encrypt('apassword') ),&lt;br /&gt; ('vivita@blobber.org','vivita','vivita/', encrypt('anotherpassword') );&lt;br /&gt;&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt; ('xandros@blobber.org','xandros@blobber.org'),&lt;br /&gt; ('vivita@blobber.org','vivita@blobber.org');&lt;br /&gt;You want all mail for whooper.nu to go to xandros (catchall).&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt;  ('@whopper.nu','xandros@blobber.org');&lt;br /&gt;There is also a "Karl" user, but he does want all mail forwarded to an external account.&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt; ('karl@blobber.org','karl.vovianda@gmail.com');&lt;br /&gt;So what does each of these lines actually do? Well the domains are pretty straight forward.&lt;br /&gt;The users are as well, it requires four fields. ID is the email address of the user, and also its username when loggin in, described later on. NAME is optional description of the user. MAILDIR is the name of the folder inside /var/spool/mail/virtual. It must end in a /, otherwise it wont be used as a unix maildir format. CRYPT is the encrypted text password to use.&lt;br /&gt;The alises are the interesting part. Lets start from a top down view to see how emails get delivered:&lt;br /&gt;Say an email arrives addressed to "john@whopper.nu".&lt;br /&gt;Postfix looks up domains and say whopper.nu is an domain it listens to.&lt;br /&gt;Postfix then looks up aliases and searches for a row where the mail field matches "john@whopper.nu".&lt;br /&gt;None does so it next searches for "@whopper.nu", which is the way to specify catch all others for that domain.&lt;br /&gt;It finds one row and its destination is "xandros@blobber.org".&lt;br /&gt;It then searches for "xandros@blobber.org" and finds one, which destination is the same as the mail, therefor it is the final destination.&lt;br /&gt;It then tries to deliver this mail. The look up says blobber.org is a local mail so it looks up users for a matching id and delivers it to its maildir.&lt;br /&gt;Lets try "julian.whippit@lala.com".&lt;br /&gt;Postfix looks up domains and it is an domain it listens to.&lt;br /&gt;First lookup does not find this user, but the next finds the catchall "@lala.com". But its destination is another catchall, "@blobber.org".&lt;br /&gt;This means Postfix will look for "julian.whippit@blobber.org". This address is not found either, nor is a catchall for blobber.org. Therefor this address is not valid and the message will be bounced.&lt;br /&gt;Any mail arriving for "karl@blobber.org" or "karl@lala.com", gets forward to an external address of "karl.vovianda@gmail.com". So forwarding is simple. I tend to use a subdomain for all my friends addresses as easily I forget what their real addresses are, and I use different email clients all the time.&lt;br /&gt;I also added the required aliases of postmaster and abuse to blobber.org and whopper.nu. The catchall for lala.com means they are not required for that domain.&lt;br /&gt;Another useful alias to add is root, as often you get admin mail from e.g cron jobs within those domains etc. Other often used aliases are info, sysadmin, support, sales, webmaster, mail, contact and all. But they are also honeypots for spam, so just include the ones you think you will need.&lt;br /&gt;Adding template&lt;br /&gt;So to add a new domain to the system, You do this, replacing the italics with relevant data:&lt;br /&gt;INSERT INTO domains (domain) VALUES ('domain.tld');&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt; ('@domain.tld','email@address'),&lt;br /&gt; ('postmaster@domain.tld','email@address'),&lt;br /&gt; ('abuse@domain.tld','email@address');&lt;br /&gt;And to add a new user to the system, do this:&lt;br /&gt;INSERT INTO users (id,name,maildir,clear) VALUES&lt;br /&gt; ('email@address','short description','foldername/',encrypt('password') );&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt; ('email@address','email@address');&lt;br /&gt;Return to top.&lt;br /&gt;Common SQL&lt;br /&gt;A selection of useful sql statements, if you are not using an admin/manager program to maintain your email domains and users.&lt;br /&gt;Find domains without a catchall&lt;br /&gt;#Remember some might be disabled&lt;br /&gt;SELECT dom.domain &lt;br /&gt;FROM domains dom&lt;br /&gt;LEFT JOIN aliases al&lt;br /&gt; ON CONCAT( '@', dom.domain ) = al.mail&lt;br /&gt;WHERE al.mail is null&lt;br /&gt;OR al.enabled = 0&lt;br /&gt;ORDER BY dom.domain ASC&lt;br /&gt;Find aliases for an invalid domain&lt;br /&gt;SELECT al.*&lt;br /&gt;FROM aliases al&lt;br /&gt;LEFT JOIN domains dom&lt;br /&gt; ON dom.domain = SUBSTRING(al.mail,LOCATE('@',al.mail)+1)&lt;br /&gt;WHERE dom.domain is null&lt;br /&gt;OR dom.enabled = 0&lt;br /&gt;ORDER BY al.mail ASC&lt;br /&gt;Find all non local destination aliases&lt;br /&gt;SELECT al.*&lt;br /&gt;FROM aliases al&lt;br /&gt;LEFT JOIN domains dom&lt;br /&gt; ON dom.domain = SUBSTRING(al.destination,LOCATE('@',al.destination)+1)&lt;br /&gt;WHERE dom.domain is null&lt;br /&gt;ORDER BY al.enabled, al.destination ASC, al.mail ASC&lt;br /&gt;Find all aliases for a certain domain&lt;br /&gt;SELECT al.*&lt;br /&gt;FROM aliases al&lt;br /&gt;WHERE SUBSTRING(al.mail,LOCATE('@',al.mail)+1) = 'domain.tld'&lt;br /&gt;ORDER BY al.enabled, al.mail ASC&lt;br /&gt;Find all aliases for a certain domains, checking if enabled for both domain and alias&lt;br /&gt;select * &lt;br /&gt;from domains d&lt;br /&gt;join aliases a&lt;br /&gt;  on a.mail like concat( '%','@',d.domain)&lt;br /&gt;  and a.enabled = 1&lt;br /&gt;where d.enabled = 1&lt;br /&gt;and d.domain like '%foobar%'&lt;br /&gt;order by d.domain,a.mail&lt;br /&gt;Return to top.&lt;br /&gt;Test&lt;br /&gt; &lt;br /&gt;Common problems&lt;br /&gt;Test strategy&lt;br /&gt;Tail, tail and tail again&lt;br /&gt;Switch off services&lt;br /&gt;Switch debug on&lt;br /&gt;Telnet is your friend&lt;br /&gt;Can postfix receive?&lt;br /&gt;Can postfix send?&lt;br /&gt;Can courier read?&lt;br /&gt;Common problems&lt;br /&gt;Missed a step&lt;br /&gt;If you mistakenly or intentially skipped past sections, you may have missed an important step in your configuration, which my guide pressumes you have followed.&lt;br /&gt;Typo&lt;br /&gt;99% of all problems is spelling errors or typos you entered while following this guide. Sorry, but it just happens. Often it can be trivial, such as a space at the end of the configuration line which was not expected etc. Or not understanding my example where it is a multi line entry.&lt;br /&gt;Typo by me&lt;br /&gt;Yes, I make a lot of mistakes. Nothing wrong in that, but I hope I have corrected most over time. Any new sections are however at risk... :)&lt;br /&gt;Different application or configurations&lt;br /&gt;It is obviously entirely up to you how you set up your system. But the more you deviate from this guide, the more likely incompatibilties or confusion will arrise.&lt;br /&gt;Distrobution/version differences&lt;br /&gt;If you run a different version or even distrobution to this guide, then some things will be different. Small issues, such as default values and significant things such as path differences etc. Some sections in this guide are not always thouroughly tested with every new release of Ubuntu, but these differences gets pointed out by people for me.&lt;br /&gt;Walking before crawling&lt;br /&gt;Don't try the full blown mail server before the basics are working.&lt;br /&gt;Gamma rays and little goblins&lt;br /&gt;Got to blame it on something or someone.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Test strategy&lt;br /&gt;What steps to think of when testing.&lt;br /&gt;Test early and frequently&lt;br /&gt;It is very helpfull to test early in this set up, to establish if the first sections are working as expected.&lt;br /&gt;So when you only have your very basic postfix and mysql up: Test it!&lt;br /&gt;That way you know that bit worked and can rule it out of any future problems.&lt;br /&gt;Don't wait till you complicated and mudded the water after amavis, courier etc is added.&lt;br /&gt;By constantly testing if you can send and receive you can tick off and black box each section as working, and immidietly spot issues.&lt;br /&gt;Isolate the problem&lt;br /&gt;Testing how things work is often about isolating the problem first. So by using the steps of testing early above, you can see which step caused the problem.&lt;br /&gt;Also if you can't log into your webmail it is often nothing to do with the webmail section that is causing the problem. Often postfix itself is broken etc.&lt;br /&gt;Test in order&lt;br /&gt;As part of the isolating the problem rule, you most of the time test in order, and test each section thus isolating the problem. This would then quickly isolate the problem when e.g. such as above issues of reading emails via the webmail. This would be in order:&lt;br /&gt;Access: Can I get(ssh) to the box, and is there a firewall issue?&lt;br /&gt;Database: Is the database up, do my application reach it?&lt;br /&gt;Postfix: Can I send email by command line, do I receive emails via telnet?&lt;br /&gt;Content checks: Do they cause a problem?&lt;br /&gt;Courier: Can I read emails?&lt;br /&gt;Webmail: And last but not least does the web integration work?&lt;br /&gt;Simplify the system&lt;br /&gt;Assisting in isolating the problem, you often have to disable options and applications. Such as turn of postgrey or content checks to make sure emails to get delivered.&lt;br /&gt;Previous editions do have some more detail on how to achieve this&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Tail, tail and tail again&lt;br /&gt;Essential to monitor what actually happens, and tailing specifically the mail and mysql log.&lt;br /&gt;/var/log/system.log&lt;br /&gt;/var/log/mail.log&lt;br /&gt;/var/log/mysql.log&lt;br /&gt;/var/log/apache2/access.log&lt;br /&gt;In one window:&lt;br /&gt;tail -f /var/log/mail.log&lt;br /&gt;And in another window:&lt;br /&gt;tail -f /var/log/mysql.log&lt;br /&gt;In a third or more do your actual configuration or testing.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Switch off services&lt;br /&gt;previous edition 1&lt;br /&gt;previous edition 2&lt;br /&gt;The previous editions has detail on switching services off untill time to test them. &lt;br /&gt;It also details locking down your server from spammers untill finished testing.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Switch debug on&lt;br /&gt;Shorewall&lt;br /&gt;You can also switch on more messages for when the firewall is rejecting connections. Add info to all REJECT, BOUNCE and DROP policies.&lt;br /&gt;sudo vi /etc/shorewall/policy&lt;br /&gt;such as:&lt;br /&gt;net all DROP  info&lt;br /&gt;MySQL&lt;br /&gt;There is no point in tailing the mysql log if query debugging is not turned one. &lt;br /&gt;By default it is not. However in this guide I do switch it on, in case that was missed switch it on now:&lt;br /&gt;sudo vi /etc/mysql/my.cnf&lt;br /&gt;Make sure this is not commented out&lt;br /&gt;log = /var/log/mysql/mysql.log&lt;br /&gt;Courier&lt;br /&gt;As mentioned in the setup , switching on debugging for Courier is easy:&lt;br /&gt;sudo vi /etc/courier/authdaemonrc&lt;br /&gt;DEBUG_LOGIN=2&lt;br /&gt;Amavis&lt;br /&gt;You can also debug amavis:&lt;br /&gt;sudo vi /etc/amavis/conf.d/50-user&lt;br /&gt;And perhaps bump it up if already debugging:&lt;br /&gt;$log_level = 2;&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Telnet is your friend&lt;br /&gt;When testing a mail server, telnet is alpha &amp; omega. You use it to simulate real mail servers to test responses by your mail server.&lt;br /&gt;First you test it on the server to exclude firewall and network issues.&lt;br /&gt;Then you test it from another machine to simulate an actual other mail server.&lt;br /&gt;Once these are working you can use proper email clients, however 99% I just use mutt locally when I need to test if a server is working.&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Can postfix receive?&lt;br /&gt;Lets assume:&lt;br /&gt;You have followed my guide up to basic configuration at least&lt;br /&gt;You have entered data into the database&lt;br /&gt;The services MySQL and Postfix are running.&lt;br /&gt;If testing a fuller stack, then amavis, postgrey, clamav-daemon, spamassassin etc must also be running.&lt;br /&gt;Try this locally on the server first, then try from another machine once it is working locally.&lt;br /&gt;Lets try and send a message to xandros@example.org (replace with your own user in this setup, or use postmaster@localhost) from you@example.com (again replace with a real email address you use that is not associated with this server.)&lt;br /&gt;telnet localhost 25&lt;br /&gt;# Open the hand shake with ehlo and the server name you are connecting from...&lt;br /&gt;# Change mail.example.com to something valid eg your servername&lt;br /&gt;EHLO mail.example.com&lt;br /&gt;# The mail server will then dump out some details about its capabilities, e.g.&lt;br /&gt;&gt;250-mail.flurdy.net&lt;br /&gt;&gt;250-PIPELINING&lt;br /&gt;&gt;....&lt;br /&gt;&gt;....&lt;br /&gt;# then say who is the sender of this email&lt;br /&gt;MAIL FROM: &lt;your@example.com&gt;&lt;br /&gt;&gt; 250 Ok&lt;br /&gt;# then say who the mail is for&lt;br /&gt;RCPT TO: &lt;xandros@example.org&gt;&lt;br /&gt;&gt; 250 Ok&lt;br /&gt;# then enter the keyword data&lt;br /&gt;data&lt;br /&gt;&gt; 354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;&lt;/LF&gt;&lt;/CR&gt;&lt;/LF&gt;&lt;/CR&gt;&lt;br /&gt;# enter message bodyand end with a line with only a full stop.&lt;br /&gt;blah blah blah&lt;br /&gt;more blah&lt;br /&gt;.&lt;br /&gt;&gt; 250 Ok; queued as QWKJDKASAS&lt;br /&gt;# end the connection with&lt;br /&gt;quit&lt;br /&gt;&gt; 221 BYE&lt;br /&gt;If while you were doing this you were tailing the /var/log/mail.log you would see some activities and if any errors occured. (You should probably get some complaints about missing headers as we skipped most...)&lt;br /&gt;If while you were doing this you were tailing the /var/log/mysql.log as well you really should have seen some activity otherwise you have a problem.&lt;br /&gt;If you see any errors (or worse no activity) in these log files, this is what you need to fix! For common problems and solutions check the previous edition.&lt;br /&gt;&lt;br /&gt;However if no errors popped up, and the folder /var/mail/virtual/xandros now exists then your server can receive emails!&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;Can postfix send?&lt;br /&gt;You need to make sure you can first receive emails as above&lt;br /&gt;The services MySQL and Postfix are running.&lt;br /&gt;Basically you just tested that above, but we need double check if it can send out to other servers. Again we will first test locally, which should work, then remotely which introduces many possible problems.&lt;br /&gt;telnet localhost 25&lt;br /&gt;# Open the hand shake with ehlo and the server name you are connecting from...&lt;br /&gt;# This time it has to be the name of your server&lt;br /&gt;EHLO mail.example.org&lt;br /&gt;# The mail server will then dump out some details about its capabilities, e.g.&lt;br /&gt;&gt;250-mail.flurdy.net&lt;br /&gt;&gt;250-PIPELINING&lt;br /&gt;&gt;....&lt;br /&gt;&gt;....&lt;br /&gt;# then say who is the sender of this email, which is a local user&lt;br /&gt;MAIL FROM: &lt;xandros@example.org&gt;&lt;br /&gt;&gt; 250 Ok&lt;br /&gt;# then say who the mail is for which is an external address e.g. gmail etc.&lt;br /&gt;RCPT TO: &lt;you@example.com&gt;&lt;br /&gt;&gt; 250 Ok&lt;br /&gt;# then enter the keyword data&lt;br /&gt;data&lt;br /&gt;&gt; 354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;&lt;/LF&gt;&lt;/CR&gt;&lt;/LF&gt;&lt;/CR&gt;&lt;br /&gt;# enter message bodyand end with a line with only a full stop.&lt;br /&gt;blah blah blah&lt;br /&gt;more blah&lt;br /&gt;.&lt;br /&gt;&gt; 250 Ok; queued as QWKJDKASAS&lt;br /&gt;# end the connection with&lt;br /&gt;quit&lt;br /&gt;&gt; 221 BYE&lt;br /&gt;We have to assume receiving works above so no need to tail mysql's logs. However if any rejection errors occured in the mail.log then you have an error.&lt;br /&gt;However if no errors occured and you see in the log something like this:&lt;br /&gt;Dec 17 10:25:45 servername postfix/smtp[12345]: 12345678: to=&lt;you@example.com&gt;, relay=127.0.0.1[127.0.0.1]:10024, &lt;br /&gt;delay=15, delays=15/0.01/0.02/0.11, dsn=2.0.0, status=sent (250 2.0.0 Ok, id=12345-09, from MTA([127.0.0.1]:10025): &lt;br /&gt;250 2.0.0 Ok: queued as 1234567)&lt;br /&gt;Then the sending emails work!&lt;br /&gt;Return to top.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Can courier read emails&lt;br /&gt;You need to make sure you can first receive emails as above&lt;br /&gt;You need to make sure you can send emails as above&lt;br /&gt;You need to make sure you have received an email and the folder /var/mail/virtual/xandros exists&lt;br /&gt;The services MySQL, courier-authdaemon and courier-imap are running.&lt;br /&gt;There is not too much you can test via telnet for courier. But you can check if it is up and you can connect to it.&lt;br /&gt;telnet 127.0.0.1 143&lt;br /&gt;Trying 127.0.0.1...&lt;br /&gt;Connected to 127.0.0.1.&lt;br /&gt;Escape character is '^]'.&lt;br /&gt;* OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT&lt;br /&gt;  QUOTA IDLE ACL ACL2=UNION STARTTLS LOGINDISABLED] Courier-IMAP ready. Copyright 1998-2008&lt;br /&gt;  Double Precision, Inc.  See COPYING for distribution information.&lt;br /&gt;The rest you would have to test via a proper email IMAP client.&lt;br /&gt;Can amavis check and pass emails along?&lt;br /&gt;You need to make sure you can first receive emails as above&lt;br /&gt;You need to make sure you can send emails as above&lt;br /&gt;You need to make sure you have received an email and the folder /var/mail/virtual/xandros exists&lt;br /&gt;You can check if the service is responding:&lt;br /&gt;telnet 127.0.0.1 10024&lt;br /&gt;Trying 127.0.0.1...&lt;br /&gt;Connected to 127.0.0.1.&lt;br /&gt;Escape character is '^]'.&lt;br /&gt;220 [127.0.0.1] ESMTP amavisd-new service ready&lt;br /&gt;Then just tail /var/log/mail.log for any problems.&lt;br /&gt;Return to top.&lt;br /&gt;Initialize&lt;br /&gt;Brief hints if you receive a ready setup machine (or EC2 AMI), and what then to check and to customize it to your setup.&lt;br /&gt;Stop services&lt;br /&gt;Restrict firewall&lt;br /&gt;Change passwords&lt;br /&gt;Check configurations&lt;br /&gt;Set machine name&lt;br /&gt;Certificates&lt;br /&gt;Start and test services&lt;br /&gt;Insert data&lt;br /&gt;Reload postfix&lt;br /&gt;Open firewall&lt;br /&gt;Test&lt;br /&gt;Stop services&lt;br /&gt;First stop services so they wont accidentally do something.&lt;br /&gt;sudo /etc/init.d/postfix stop&lt;br /&gt;sudo /etc/init.d/courier-imap-ssl stop&lt;br /&gt;sudo /etc/init.d/courier-imap stop&lt;br /&gt;sudo /etc/init.d/courier-authdaemon stop&lt;br /&gt;sudo /etc/init.d/mysql stop&lt;br /&gt;sudo /etc/init.d/amavisd stop&lt;br /&gt;sudo /etc/init.d/spamassassin stop &lt;br /&gt;sudo /etc/init.d/clamav stop&lt;br /&gt;Restrict firewall&lt;br /&gt;Check what the firewall rules are.&lt;br /&gt;vi /etc/shorewall/rules&lt;br /&gt;Refer to the firewall settings. Restrict to just SSH access for now.&lt;br /&gt;Change passwords&lt;br /&gt;Next the passwords needs to be changed. For both the system and mysql.&lt;br /&gt;System passwords&lt;br /&gt;Check which users are defined on the system.&lt;br /&gt;cat /etc/passwd&lt;br /&gt;Apart from all the system ones, there should probably be none (if EC2 AMI) or just your user if it is a standard Ubuntu install. If there are some users, you need to change their passwords.&lt;br /&gt;SSH Access&lt;br /&gt;Next we check whom got SSH access. If there was any users defined, check their home folders for ssh keys.&lt;br /&gt;cat /home/username/.ssh/auth*&lt;br /&gt;Remove any you do not expect to be there. Next check if and which specific users has been defined for SSH access in&lt;br /&gt;vi /etc/ssh/sshd&lt;br /&gt;Usually this is fine.&lt;br /&gt;MySQL passwords&lt;br /&gt;First you need to change the root mysql user. If none has been set do this&lt;br /&gt;mysqladmin -u root password new_password&lt;br /&gt;Otherwise do this and you will be prompted for the old password&lt;br /&gt;mysqladmin -u root password new_password -p&lt;br /&gt;Then the default mail user as well. If you know the old password&lt;br /&gt;mysqladmin -u mail password new_password -p&lt;br /&gt;Otherwise log into mysql as root:&lt;br /&gt;mysql -u root -p&lt;br /&gt;Enter new root password specified above, then:&lt;br /&gt;update mysql.user set password=password('apassword') where user='mail';&lt;br /&gt;flush privileges;&lt;br /&gt;You may need to revisit the top of MySQL section to re-grant the mail use rights on the database.&lt;br /&gt;If you do not know the old root password, you have to restart mysql without grant rights. Google it... :)&lt;br /&gt;Update postfix mysql configuration files with the new password.&lt;br /&gt;sudo vi /etc/postfix/mysql*&lt;br /&gt;password=apassword&lt;br /&gt;Update courier's authmysql file with the new password as well.&lt;br /&gt;sudo vi /etc/courier/authmysqlrc&lt;br /&gt;MYSQL_PASSWORD apassword&lt;br /&gt;If SASL is set up, then you need to update its passwords. First in postfix SASL file:&lt;br /&gt;sudo vi /etc/postfix/sasl/smtpd.conf&lt;br /&gt;sql_passw: aPASSWORD&lt;br /&gt;Then on both lines in:&lt;br /&gt;sudo vi /etc/pam.d/smtp&lt;br /&gt;passwd=aPASSWORD&lt;br /&gt;Check configurations&lt;br /&gt;You should scan the postfix, courier, etc. configurations to check if they match what you expect.&lt;br /&gt;Set machine name&lt;br /&gt;Now you need to define your machine name, e.g. something like smtp.yourdomain.com. You need to define it in&lt;br /&gt;sudo vi /etc/mailname&lt;br /&gt;And then your domain name in&lt;br /&gt;sudo vi /etc/postfix/main.cf&lt;br /&gt;under the mydomain setting&lt;br /&gt;myorigin=yourdomain.com&lt;br /&gt;It could also be smart to check what the unix hostname is specified as&lt;br /&gt;hostname&lt;br /&gt;This can be reset by&lt;br /&gt;sudo hostname smtp.yourdomain.com.&lt;br /&gt;All though this does not have to be the same as your postfix mail server name.  You may want to speficiy some hosts in hosts file as well,&lt;br /&gt;sudo vi /etc/hosts&lt;br /&gt;127.0.0.1 localhost.localdomain localhost&lt;br /&gt;127.0.0.1 smtp.yourdomain.com smtp&lt;br /&gt;Certificates&lt;br /&gt;You could go along with the generated certificates (if they are there, default for Ubuntu). Or if you could create new ones with the correct machine name in them. Especially if this a mail server used by many, and authenticiy is important. Follow the TLS certificate instructions for Postfix and Courier.&lt;br /&gt;Start and test services.&lt;br /&gt;Next you need to start your mail services and test them.&lt;br /&gt;sudo /etc/init.d/mysql start&lt;br /&gt;sudo /etc/init.d/spamassassin start&lt;br /&gt;sudo /etc/init.d/clamav start&lt;br /&gt;sudo /etc/init.d/amavisd start&lt;br /&gt;sudo /etc/init.d/postfix start&lt;br /&gt;sudo /etc/init.d/courier-imap-ssl start&lt;br /&gt;sudo /etc/init.d/courier-imap start&lt;br /&gt;sudo /etc/init.d/courier-authdaemon start&lt;br /&gt;So test tjenestene via testing section.&lt;br /&gt;Insert data&lt;br /&gt;Insert your mail domains, aliases and users using the data section.&lt;br /&gt;Some times there are test data already in the database. Remove them. E.g.;&lt;br /&gt;mysql -u mail -papassword maildb&lt;br /&gt;delete from domains where domain = 'bar.com';&lt;br /&gt;delete from aliases where mail = 'foo@bar.com';&lt;br /&gt;Open firewall&lt;br /&gt;Then open up the firewall, follow the world access bit in the firewall configuration. Voila. Up and running. Well we hope.&lt;br /&gt;Return to top.&lt;br /&gt;Extend&lt;br /&gt;&lt;br /&gt;Please refer to previous edition for how and why you can extend this mail server.&lt;br /&gt;By now you should have a fully working system. No point extending and complicating it untill then. What next? There are many ways to extend the server, to create your own powerfull customized version.&lt;br /&gt;Remote MX mail backup&lt;br /&gt;Relay recipient lookup&lt;br /&gt;Local file backup&lt;br /&gt;Sender ID &amp; SPF&lt;br /&gt;Spam reporting&lt;br /&gt;White/Black lists&lt;br /&gt;PGP &amp; S/MIME&lt;br /&gt;Relocation notice&lt;br /&gt;Pop-before-SMTP&lt;br /&gt;Admin Software&lt;br /&gt;Auto Reply&lt;br /&gt;Block Addresses&lt;br /&gt;Throttle Output&lt;br /&gt;Mail Lists&lt;br /&gt;Google Apps / GMail&lt;br /&gt;Roundcube webmail&lt;br /&gt;Sugestions?&lt;br /&gt;Some of these sections can be brief as they are not core to this howto.&lt;br /&gt;Remote MX mail backup&lt;br /&gt;With MX backup loosing emails are unlikely.&lt;br /&gt;Normally if someone sends an email destined for you, their server will try and connect to your server.  If it can't reach your server for whatever reason ( it is down, dns issues, there is network problems, or just too busy ), the other server will back off and try again in a bit. How many and for how long it will try again is determined by the sending server. Some of them are not very patience, and it will report undelivered after only a few attempts. So you would have lost that email.&lt;br /&gt;If you had specified a backup MX, this email may not have been lost. Upon first failure to connect to your server, the sender would see if there is any alternative server to send to. So it connects to your backup mx server. This server spools and queues your message and will try at intervals to send the message to you. It too will though eventually give up.&lt;br /&gt;What is the difference? Simple, you (or whoever controls the backup mx ) is in control how long and often to try connecting to your machine. So if you have a reasonable values and your server is not down for weeks, no mail is lost.&lt;br /&gt;How to implement it? First edit the DNS records again, and add a backup mx with a higher value.&lt;br /&gt;# your server details&lt;br /&gt;domain.tld IN MX 10 your.mailserver.name.tld&lt;br /&gt;# new backup server&lt;br /&gt;domain.tld IN MX 20 your.backupserver.name.tld&lt;br /&gt;Now presuming the other backup mx is a postfix server identical to this, or you are backuing up someone else's server; Go into mysql and create this tables:&lt;br /&gt;CREATE TABLE `backups` (&lt;br /&gt; `pkid` smallint(6) NOT NULL auto_increment,&lt;br /&gt; `domain` varchar(128) NOT NULL default '',&lt;br /&gt; `transport` varchar(128) NOT NULL default ':[]',&lt;br /&gt; `enabled` smallint(6) NOT NULL default '1',&lt;br /&gt; PRIMARY KEY  (`pkid`),&lt;br /&gt; UNIQUE KEY `domain` (`domain`)&lt;br /&gt;);&lt;br /&gt;Then still on the backup server, edit main.cf and add these:&lt;br /&gt;relay_domains = mysql:/etc/postfix/mysql_backups.cf&lt;br /&gt;transport_maps = mysql:/etc/postfix/mysql_transport.cf&lt;br /&gt;You may choose to have this as the last line in the file, as you may use small cron jobs to modify this ip address, if you don't have a permanent static address. It should contain your IP addres, hence if you do not have a very static IP address, that you need to automatic editing if the postfix file.&lt;br /&gt;proxy_interfaces = 1.2.3.4&lt;br /&gt;If someone comes with a better way, then let me know.&lt;br /&gt;Next create this file /etc/postfix/mysql_backups.cf&lt;br /&gt;user=mail&lt;br /&gt;password=apassword   &lt;br /&gt;dbname=maildb&lt;br /&gt;table=backups  &lt;br /&gt;select_field=domain&lt;br /&gt;where_field=domain&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;Next create this file /etc/postfix/mysql_transport.cf&lt;br /&gt;user=mail&lt;br /&gt;password=apassword   &lt;br /&gt;dbname=maildb&lt;br /&gt;table=backups  &lt;br /&gt;select_field=transport&lt;br /&gt;where_field=domain&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;You noticed I added a transport lookup. This is a field in both the domain and the backup tables. In domains it is used to determine how to deliver the email, ie either virtual (correct) or local (not used in this howto). When backing up servers, your also need to specify in the transport field how to connect to the correct servers.&lt;br /&gt;Say you are backiup for a friends server, mail.friend.com, for the domains of friend1.com and friend2.com. So you should insert this into your backup table.&lt;br /&gt;INSERT INTO backups (domain,transport)&lt;br /&gt;VALUES ('friend1.com' , ':[mail.friend.com]' ),&lt;br /&gt;('friend2.com' , ':[mail.friend.com]' );&lt;br /&gt;The :[] tells to connect directly to this server, not doing any more look ups for valid MX servers.&lt;br /&gt;This shouls now work fine. Further tweaking of the queue values, review these and modify as appropiate. Shorter warning times are good for the sender, so that they realise the email has not arrived yet, but may also be annoying. Tradeoffs.. Look in the first main.cf configurations for ways to do so.&lt;br /&gt;Relay recipient lookup&lt;br /&gt;Unfortunetly spammers are using backup mx as a way to saturate the networks with invalid emails, known as backscatter mail.&lt;br /&gt;They simply lookup a domain's MX servers and connect directly to one of the lower priority servers whom may be just a backup mx. This server if configured as above will not check for valid addresses aliases but will accept and queue all emails for the domain's it is configured as a backup mx for. These will then be delivered by the server later to the primary MX server, whom will then maybe reject them as the aliases are not valid. However the sender addresses are often invalid and a long trail of reject messages to and forth around the net follows...&lt;br /&gt;To avoid this you can enable relay recipient lookup in Postfix.&lt;br /&gt;Edit /etc/postfix/main.cf and add:&lt;br /&gt;relay_recipient_maps = mysql:/etc/postfix/mysql_relays.cf&lt;br /&gt;Then create a new file /etc/postfix/mysql_relays.cf&lt;br /&gt;user=mail&lt;br /&gt;password=apassword&lt;br /&gt;dbname=maildb&lt;br /&gt;table=relays&lt;br /&gt;select_field=recipient&lt;br /&gt;where_field=recipient&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;Then add the following MySQL table:&lt;br /&gt;CREATE TABLE `relays` (&lt;br /&gt; `pkid` smallint(6) NOT NULL auto_increment,&lt;br /&gt; `recipient` varchar(120) NOT NULL default '',&lt;br /&gt; `enabled` tinyint(1) NOT NULL default '1',&lt;br /&gt; `status` varchar(10) NOT NULL default 'OK',&lt;br /&gt; PRIMARY KEY  (`pkid`),&lt;br /&gt; UNIQUE KEY `recipient` (`recipient`)&lt;br /&gt;);&lt;br /&gt;If the relay_recipient_maps setting is set, then postfix will reject all email addresses not specificed in this table. As with many postfix lookups, it will recursively search for a match from the full address.&lt;br /&gt;In the following examples, emails to john@example.com are the only emails that will be accepted for the whole example.com domain. &lt;br /&gt;However for @example.org all emails will be accepted for backup, except any for support@example.org which will be rejected.&lt;br /&gt;insert into relays (recipient,status) values &lt;br /&gt;  ('john@example.com','OK'),&lt;br /&gt;  ('support@example.org','REJECT'),&lt;br /&gt;  ('@example.org','OK');&lt;br /&gt;Return to top.&lt;br /&gt;Local file backup&lt;br /&gt;Here is rough backup script to backup your configurations and mail folders. You may want to backup the folders seperatly as they can quickly grow to GBs. Adding this to a cronjob automates this process. Be aware that you should stop postfix and courier while backing up the mail folders. And that if they have grown large, that this may take some time.&lt;br /&gt;tar czf mail-config.xxxxx.tgz /etc/postfic /etc/courier /etc/spamassassin /etc/clamav /etc/amavis /etc/mysql/my.cnf&lt;br /&gt;tar czf mail-fold.xxxx.tgz /var/spool/mail/virtual&lt;br /&gt;mysqldump -u mail -papassword -t maildb &gt; data.sql&lt;br /&gt;mysqldump -u mail -papassword -d maildb &gt; schema.sql&lt;br /&gt;tar czf mail-data.xxx.tgz schema.sql data.sql&lt;br /&gt;tar cf mail.xxxxx.tar  mail-*.xxxxx.tgz &lt;br /&gt;You may combine a full backup with a intermediate update of what has changed recently only.&lt;br /&gt;tar --newer-mtime "2005-01-01"&lt;br /&gt;Return to top.&lt;br /&gt;Sender ID &amp; SPF&lt;br /&gt;Further security features is using Microsoft's Sender ID or Pobox's SPF. I'd use SPF as there is much argument over Sender ID.&lt;br /&gt;spf.pobox.com&lt;br /&gt;www.microsoft.com/mscorp/safety/technologies/senderid/&lt;br /&gt;SPF should limit who can send mail on behalf of your domains, and is an open design. I do recommend SPF, with some reservations, detailed below.&lt;br /&gt;While Microsoft is not always entirely evil, as sometimes they do nice things and make some useful software, I would prefer not to be locked into their Sender ID technology.&lt;br /&gt;SPF configuration&lt;br /&gt;The pobox site has some nice SPF generation tools to setup your SPF configuration. Probably best to use theirs.&lt;br /&gt;But the way I have my setup, is generally one domain with detailed SPF, then all other domains just with an SPF alias to it. e.g:&lt;br /&gt;Main domain DNS TXT field:&lt;br /&gt;"v=spf1 a mx a:myserver.example.com include:aspmx.googlemail.com include:gmail.com ~all"&lt;br /&gt;The important elements are:&lt;br /&gt;I list the mail servers and websites associated with this domain (the a and mx bit).&lt;br /&gt;I then specifically list the name of a server I may send mail from applications automatically using addresses within this domain.&lt;br /&gt;As you can see I also use Google Apps with this domain, thus tell SPF to also allow all mail servers associated with google mail.&lt;br /&gt;Then for most of the other domains I would use this DNS TXT field:&lt;br /&gt;"v=spf1 a mx include:example.com ~all"&lt;br /&gt;The important elements are:&lt;br /&gt;I list the mail servers and websites associated with this domain&lt;br /&gt;Then I tell SPF to also allow all mail servers associated with my main domain (example.com).&lt;br /&gt;And for all these I use ~all!&lt;br /&gt;Ps. Some domains I have added an even stricter SPF, as these are domains that will never send an email.&lt;br /&gt;SPF problem&lt;br /&gt;It is worth noting about SPF, that you should leave the decision to whether to reject or allow the email to the mail servers. Therefor using -all instead of ~all is not a good choice. Leave it to the SPAM scoring by the receiving server, like SpamAssasin does it. You then minimise the risk of false positives.&lt;br /&gt;One of the reason I do discourage -all use, is that SPF has a distinct problem:&lt;br /&gt;It does not like email forwarding or use of backup MX!&lt;br /&gt;Consider this: Your address of lulu@hoopa.com sends a joke email to a few friends. One of these is trixie@bellbell.org.&lt;br /&gt;Trixie's email address is actually an alias and forwards the email to her private webmail account on hotmailnot.com.&lt;br /&gt;Now if your domain, hoopa.com, have a strict SPF set up, which only allows emails to be sent by its mail server. And you/the mail admin has added -all to the SPF, which tells other server to reject emails not from your server. This you think makes sense, spammers can not use your domain for spoof emails.&lt;br /&gt;So what happens: bellbell.org receives the email from lulu, and possible checks the SPF, which is OK, and forwards it on to hotmailnot.com.&lt;br /&gt;However if hotmailnot.com also checks SPF, it will receive the email from bellbell.org, check the SPF to see bellbell.org's mail server is allowed to send emails on behalf hoopa.com. SPF will say No!, and with the -all, hotmailnot.com email server will reject the email!&lt;br /&gt;2nd scenario if lulu email trixie directly at hotmailnot.com, but hotmailnot.com main mail server was down, and email was sent to the backup mx server. When the main server came online again, and the backup spooled the email back to it, the SPF would again fail as the hoopa.com's SPF would not mention hotmailnot.com backup mx as an allowed mail server.&lt;br /&gt;Solution: &lt;br /&gt;Of course you can not list all possible forwarding / backup mx email server that your domain's users might at some point email!&lt;br /&gt;I simple just use the ~all option. Which simple say it is not the expected server, but probably ok. &lt;br /&gt;And if this is added to a scoring by the receiver, then the accumulated spam score might be enough to reject dodgy emails.&lt;br /&gt;Return to top.&lt;br /&gt;Spam reporting&lt;br /&gt;todo&lt;br /&gt;Reporting spam to Pyzor, Razor and SpamCop, for collaboration in spam fighting.&lt;br /&gt;More detail on SpamCop is here.&lt;br /&gt;pyzor.sourceforge.net&lt;br /&gt;razor.sourceforge.net&lt;br /&gt;Return to top.&lt;br /&gt;White/Black Lists&lt;br /&gt;todo&lt;br /&gt;You can implement white and black lists to explicitly allow or block domains and users.&lt;br /&gt;You have already visited the option of a blackhole list of known open relays in the postfix configuration.&lt;br /&gt;You can implement further lists inside Postfix or SpamAssassin. Amavisd-new already has a few well known white/black listed items in its config files. SpamAssissin also as a feture to automaticly learn white lists.&lt;br /&gt;Return to top.&lt;br /&gt;PGP &amp; S/MIME&lt;br /&gt;Adding support for GnuPG and S/MIME increases indiviual security.&lt;br /&gt;This is not implemented on the postfix server side, as this totally a client side option.&lt;br /&gt;However SquirrelMail has a GnuPG option. It is a plugin that can be downloaded from their website. Which can then be enabled via SquirrelMail's config script.&lt;br /&gt;Here is how to create a GnuPG key pair.&lt;br /&gt;# check you have not already got a key&lt;br /&gt;gpg --list-keys&lt;br /&gt;# then create one&lt;br /&gt;gpg --gen-key&lt;br /&gt;To import GnuPG into Evolution; in your settings/preferences edit your account settings and add you private key under the security tab. The private key is found via listing the GnuPG keys as above, then it is the 8 characters after the "sub 1024g/" bit of you key.&lt;br /&gt;To use GnuPG with Thunderbird you need to install EnigMail.&lt;br /&gt;S/MIME is another way to encrypt and/or sign messages. You can create you own certificate or use known organizations like Thawte. (Thawte was originally set up by the Ubuntu founder)&lt;br /&gt;Return to top.&lt;br /&gt;Relocation notice&lt;br /&gt;If people change addresses, a bounced message stating so if people send email to the old address is quite useful. To implement this in postfix, frst create a lookup table in the database.&lt;br /&gt;CREATE TABLE `relocated` (&lt;br /&gt;`pkid` smallint(6) NOT NULL auto_increment,&lt;br /&gt;`oldadr` varchar(128) NOT NULL default '',&lt;br /&gt;`newadr` varchar(128) NOT NULL default '',&lt;br /&gt;`enabled` tinyint(1) NOT NULL default '1',&lt;br /&gt;PRIMARY KEY  (`pkid`),&lt;br /&gt;UNIQUE KEY `oldadr` (`oldadr`)&lt;br /&gt;) ;&lt;br /&gt;Then add this to /etc/postfix/main.cf&lt;br /&gt;relocated_maps = mysql:/etc/postfix/mysql_relocated.cf&lt;br /&gt;The create this file /etc/postfix/mysql_relocated.cf&lt;br /&gt;user=mail&lt;br /&gt;password=apassword   &lt;br /&gt;dbname=maildb&lt;br /&gt;table=relocated  &lt;br /&gt;select_field=newadr&lt;br /&gt;where_field=oldadr&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;Then if pete@domain1.com has changed address to pete.jones@another.org:&lt;br /&gt;INSERT INTO relocated (oldadr,newadr)VALUES&lt;br /&gt;('pete@domain1.com','pete.jones@another.org');&lt;br /&gt;If anyone sends an email to pete@domain.com, they will get a message back stating he has changed address to pete.jones@another.org.&lt;br /&gt;Return to top.&lt;br /&gt;Pop-before-SMTP&lt;br /&gt;If SASL didn't work, or you are using clients which dont support it, the Pop-Before-SMTP is an easy way around that issue, so that people externally can still securly send mail via your server.&lt;br /&gt;Refer to my 2nd edition on Pop-before-SMTP setup.&lt;br /&gt;Return to top.&lt;br /&gt;Admin software&lt;br /&gt;todo&lt;br /&gt;Trying out a few admin software might make you life easier, if phpMyAdmin gets to crude. Quick search&lt;br /&gt;More to come later.&lt;br /&gt;Return to top.&lt;br /&gt;Auto Reply&lt;br /&gt;todo&lt;br /&gt;Postfix have now features to auto reply to an email, while still delivering it to its alias.&lt;br /&gt;Return to top.&lt;br /&gt;Block Addresses&lt;br /&gt;If you use catch alls, which are useful for some domains, then eventually some addresses will be target for spam. You can then either stop the catch all, or stop indivdual addresses.&lt;br /&gt;By implementing a lookup and adding this restriction to smtpd_recipient_restrictions accomplises this.&lt;br /&gt;check_recipient_access mysql:/etc/postfix/mysql_block_recip.cf,&lt;br /&gt;smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, \&lt;br /&gt; check_recipient_access mysql:/etc/postfix/mysql_block_recip.cf, \&lt;br /&gt; reject_non_fqdn_recipient, reject_unauth_destination, \&lt;br /&gt; check_relay_domains&lt;br /&gt;Beware of the order is important here, if any options says ok before check_recipient_access it will ignore it.&lt;br /&gt;Next create mysql_block_recip.cf to lookup addresses. Either create a another table, or add a blocked field to aliases table.&lt;br /&gt;Return to top.&lt;br /&gt;Throttle Output&lt;br /&gt;todo&lt;br /&gt;For some users with restrictions on bandwidth, you may wish to control how much mail is sendt out. Postfix has long refused to implement these features, out of ideolocial beliefs that mail servers should not be restricted. However there are some ways around this. More to come later.&lt;br /&gt;Return to top.&lt;br /&gt;Mail Lists&lt;br /&gt;Rich Brown has written a howto on adding Mailman, a mail list program, to my howto.  Click here to read it.&lt;br /&gt;Do note it is not part of my howto, so do not contact me regarding it. And although I think it is fine, I can't guarantee it will work.&lt;br /&gt;If you do need assistance or need to talk about it, contact Rich via his howto or use the forums for this howto.&lt;br /&gt;If you want a simple mailling list, it can be implemented by simply seperating aliases in the destination field in the aliases table with a comma.&lt;br /&gt;INSERT INTO aliases (mail,destination) VALUES&lt;br /&gt;( 'listof@domain.com' , 'john@ppp.com,vic@domain.com,jj@somewhere.tld' );&lt;br /&gt;Return to top.&lt;br /&gt;Google Apps / GMail&lt;br /&gt;I have for various reasons integrated some Google Apps hosted domains into my mail server. And you can still have good control over the addresses by using your server with Google Apps.&lt;br /&gt;More information on Google Apps.&lt;br /&gt;Why&lt;br /&gt;Some already have their domain's email hosted with Google.&lt;br /&gt;Some people prefer Google's web based interface.&lt;br /&gt;Temporary Migrations.&lt;br /&gt;Include Google's security features on top of yours.&lt;br /&gt;How&lt;br /&gt;Options&lt;br /&gt;The easiest and simples solution is not to have a domain MXed to your server, and simply alias email to those domains. eg All email to joeblogs.co.uk hosted on your server are forwarded to joeblogs.com hosted with google.&lt;br /&gt;You may set up your own server to simple be a mail server backup (mx) for a domain hosted with google. If you are the first priority in the MX details of the DNS, you still have some control, but not all will obey the priority listing. E.g. spammers, but some valid senders as well.&lt;br /&gt;However the one I use and the option where you are most in control is to keep you server as the only MX server in the DNS. And only forward certain aliases onto Google after all your servers checks. Other aliases and user can just use your mail server if you prefer. I will explain how to do this in the next steps.&lt;br /&gt;DNS&lt;br /&gt;You only put your mail server as the mx for the domain in question. Google will complain about this, as it will not be able to verify that email is setup correctly. Ignore this as it will still accept emails.&lt;br /&gt;MySQL tables&lt;br /&gt;You setup you aliases as normal. However you domain table needs tweaking. This is because otherwise your server will just forward the email to itself. You can actually specify aliases in the domain table.&lt;br /&gt;Example&lt;br /&gt;If for example:joe@bloggs.com wants to use gmail. mary@bloggs.com does not.&lt;br /&gt;If not already configured as a backup mx:&lt;br /&gt;Add a transport lookup to your /etc/postfix/main.cf file:&lt;br /&gt;transport_maps = mysql:/etc/postfix/mysql_transport.cf&lt;br /&gt;Then create /etc/postfix/mysql_transport.cf file:&lt;br /&gt;user=mail&lt;br /&gt;password=apassword&lt;br /&gt;dbname=maildb&lt;br /&gt;table=backups&lt;br /&gt;select_field=transport&lt;br /&gt;where_field=domain&lt;br /&gt;hosts=127.0.0.1&lt;br /&gt;additional_conditions = and enabled = 1&lt;br /&gt;Assuming there are no bloggs.com data in any tables (domain,alias,users,relays,backups):&lt;br /&gt;insert into domains (domain,transport) values &lt;br /&gt;  ('joe@bloggs.com','smtp:[aspmx.l.google.com]:587'),&lt;br /&gt;  ('bloggs.com','virtual:');&lt;br /&gt;insert into aliases (mail,destination) values &lt;br /&gt;  ('joe@bloggs.com','joe@bloggs.com'),&lt;br /&gt;  ('mary@bloggs.com','mary@bloggs.com');&lt;br /&gt;insert into users (id,name,maildir,crypt) values &lt;br /&gt;  ('mary@bloggs.com','mary','bloggs.com/mary',encrypt('maryspassword') );&lt;br /&gt;The domains insert is the interesting one. The transport map lookup checks recursively for an alias match and will first look for user@domain before it looks at the general bloggs.com for which transport to use. The square brackets around aspmx.l.google.com indicates that this server will not lookup for mx settings for this domains DNS, but instead connect directly. (This can avoid never ending recursive lookups/relays)&lt;br /&gt;Note if you have backup mx configured and chosen to enable relay recipient lookup to avoid backscatter mail spam, then you need to add your Google Apps users to the relays table:&lt;br /&gt;insert into relays (recipient,status) values ('joe@bloggs.com','OK');&lt;br /&gt;Refer to backup mx section for creation of this table.&lt;br /&gt;TLS certificate&lt;br /&gt;If you have set your server up to prefer TLS then you should add Google's signing authority to your server's root certificate list. Google used to use Thawte but now use Equifax.&lt;br /&gt;Download the Equifax Secure Certificate Authority certificate from their website (the base-64 encoded):&lt;br /&gt;wget http://www.geotrust.com/resources/root_certificates/certificates/Equifax_Secure_Certificate_Authority.cer;&lt;br /&gt;You need to fix the line endings in this file by either using sed:&lt;br /&gt;sed -i 's/.$//' Equifax_Secure_Certificate_Authority.cer;&lt;br /&gt;Or install a tiny util:&lt;br /&gt;sudo aptitude install tofrodos;&lt;br /&gt;fromdos Equifax_Secure_Certificate_Authority.cer;&lt;br /&gt;Put it into your certificate root folder:&lt;br /&gt;sudo chown root:root Equifax_Secure_Certificate_Authority.cer;&lt;br /&gt;sudo mv Equifax_Secure_Certificate_Authority.cer /usr/share/ca-certificates/mozilla/;&lt;br /&gt;cd /etc/ssl/certs;&lt;br /&gt;sudo ln -s /usr/share/ca-certificates/mozilla/Equifax_Secure_Certificate_Authority.cer .;&lt;br /&gt;And then append it to the root list that postfix knows about:&lt;br /&gt;sudo su;&lt;br /&gt;cat Equifax_Secure_Certificate_Authority.cer &gt;&gt; ca-certificates;&lt;br /&gt;exit;&lt;br /&gt;sudo service postfix restart;&lt;br /&gt;Issues&lt;br /&gt;There are some items you should consider when integrating Google Apps.&lt;br /&gt;Privacy&lt;br /&gt;First there is the privacy issue. This is the same as if you were using Google Apps only or GMail. Google can and will read your email. However probably not a person, but they will use it for commercial reasons, E.g. showing relevant ads. Some people really hate this part and refuse to use Google's mail products. However I trust them a little bit, and do use it.&lt;br /&gt;Spam&lt;br /&gt;If you forward spam, then consider your own servers reputation. Should be okay though.&lt;br /&gt;SPF&lt;br /&gt;If you use SPF for your domain, consider that both your server and google will receive and send mail on behalf of that domin. Adding&lt;br /&gt;include:_spf.google.com&lt;br /&gt;should cover it.&lt;br /&gt;Google internally&lt;br /&gt;Be aware Google think they host you domain. So if others inside google, or using google hosted apps or GMail, if they email you, the email may not go via your email server, but directly to the Google Apps for your domain. That could be an issue if not all aliases you have use Google Apps. This needs to be tested more though. Especially as it may only be an issue if Google's servers are part of you domains MXs. It may be worth adding aliases in your Google Apps admin for the non google apps adresses to some user whom can handle these?&lt;br /&gt;Return to top.&lt;br /&gt;Maildrop, spam folder and vacation messaging&lt;br /&gt;Villu have documented swapping in Maildrop for virtual transport and automatically deliverin spam to a spam folder. (And links to a post about vacation messaging)&lt;br /&gt;Please read his post here.&lt;br /&gt;Return to top.&lt;br /&gt;Roundcube webmail client&lt;br /&gt;As an alternative to SquirrelMail, Roundcube has a more modern feel to it. It is however not got the long testing track record of SquirrelMail, and is not yet a 1.0 release version. However if you prefer its very much more appealing interface then follow these easy steps:&lt;br /&gt;You may optionally want to uninstall SquirrelMail:&lt;br /&gt;sudo aptitude remove squirrelmail squirrelmail-locales&lt;br /&gt;Then install Roundcube&lt;br /&gt;sudo aptitude install roundcube roundcube-mysql&lt;br /&gt;It will ask you if you want to configure its database access, answer yes, then select mysql. Then it will ask for the root mysql uses password, which it will create a roundcube mysql user and ask for its desired password.&lt;br /&gt;This will create a symblink in /etc/apache2/conf.d/ to /etc/roundcube/apache.conf. Edit this file.&lt;br /&gt;sudo vi /etc/roundcube/apache.conf&lt;br /&gt;Depending on your setup you may want to move those Alias commands at the top to your virtual hosts configuration, or for this example enable them here for all hosts.&lt;br /&gt;# Uncomment them to use it or adapt them to your configuration&lt;br /&gt;Alias /roundcube/program/js/tiny_mce/ /usr/share/tinymce/www/&lt;br /&gt;Alias /roundcube /var/lib/roundcube&lt;br /&gt;Next edit the configuration file&lt;br /&gt;sudo vi /etc/roundcube/main.inc.php&lt;br /&gt;Modify these lines for added security and ease of log in:&lt;br /&gt;$rcmail_config['default_host'] = 'ssl://localhost:993';&lt;br /&gt;&lt;br /&gt;$rcmail_config['smtp_server'] = 'ssl://localhost';&lt;br /&gt;&lt;br /&gt;$rcmail_config['smtp_port'] = 465;&lt;br /&gt;&lt;br /&gt;# keep as default or change to your mail server name&lt;br /&gt;$rcmail_config['smtp_helo_host'] = 'mail.example.com';&lt;br /&gt; &lt;br /&gt;$rcmail_config['create_default_folders'] = TRUE;&lt;br /&gt;There are other tweaks and security features you can enable such as:&lt;br /&gt;$rcmail_config['sendmail_delay'] = 1;&lt;br /&gt;But perhaps concentrate on getting the basics working firtst...&lt;br /&gt;Save, exit and reload Apache to enable these aliases for Roundcube to work&lt;br /&gt;sudo /etc/init.d/apache2 reload&lt;br /&gt;Then go to your roundcube installation depending where and how you modified those Aliases, e.g. at http://mail.example.com/roundcube.&lt;br /&gt;That should be it&lt;br /&gt;You can obviously modify and tweak further. One thing that may be usefull is to have the Roundcube Apache Alias on different virtual hosts, and configure username_domain in main.inc.php to append different email addresses, or configure the default_host to different mail server depending on virtual host... More details on the Roundcube Wiki.&lt;br /&gt;Return to top.&lt;br /&gt;Suggestions?&lt;br /&gt;If you have any suggestions to other ways of extending a postfix server, then fire off a mail to me via the contact form further down.&lt;br /&gt;(Or rather, Id prefer that you write down the extension, and let me know the link! :))&lt;br /&gt;Return to top.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-8211467478027776428?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/8211467478027776428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=8211467478027776428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8211467478027776428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8211467478027776428'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2011/03/how-to-set-up-mail-server-on-gnu-linux.html' title='How to set up a mail server on a GNU / Linux system'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-52775690756105410</id><published>2011-02-25T22:02:00.000+08:00</published><updated>2011-02-25T22:03:16.387+08:00</updated><title type='text'>mencoder commands</title><content type='html'>//To DIVX&lt;br /&gt;&lt;br /&gt;mencoder -oac mp3lame -lameopts aq=7:cbr:br=128 -srate 44100 -vf scale=width:height,harddup -ovc lavc -ffourcc DX50 -lavcopts vcodec=mpeg4:vbitrate=320 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To DIVX(2pss)&lt;br /&gt;&lt;br /&gt;mencoder -nosound -vf scale=width:height,harddup -ovc lavc -ffourcc DX50 -lavcopts vcodec=mpeg4:vbitrate=320:vpass=1 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;mencoder -oac mp3lame -lameopts aq=7:cbr:br=128 -srate 44100 -vf scale=width:height,harddup -ovc lavc -ffourcc DX50 -lavcopts vcodec=mpeg4:vbitrate=320:vpass=2 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To XVID&lt;br /&gt;&lt;br /&gt;mencoder -oac mp3lame -lameopts aq=7:cbr:br=128 -srate 44100 -vf scale=width:height,harddup -ovc xvid -xvidencopts bitrate=320 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To XVID(2pss)&lt;br /&gt;&lt;br /&gt;mencoder -nosound -vf scale=width:height,harddup -ovc xvid -xvidencopts bitrate=320:pass=1 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;mencoder -oac mp3lame -lameopts aq=7:cbr:br=128 -srate 44100 -vf scale=width:height,harddup -ovc xvid -xvidencopts bitrate=320:pass=2 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To x264&lt;br /&gt;&lt;br /&gt;mencoder -oac mp3lame -lameopts aq=7:cbr:br=128 -srate 44100 -vf scale=width:height,harddup -ovc x264 -x264encopts bitrate=320 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To x264(2pss)&lt;br /&gt;&lt;br /&gt;mencoder -nosound -vf scale=width:height,harddup -ovc x264 -x264encopts bitrate=320:pass=1 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;mencoder -oac mp3lame -lameopts aq=7:cbr:br=128 -srate 44100 -vf scale=width:height,harddup -ovc x264 -x264encopts bitrate=320:pass=2 InputFile -o OutputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//视频滤镜&lt;br /&gt;&lt;br /&gt;... -vf ...,eq=B:C,...harddup ... B=亮度，C=对比度&lt;br /&gt;... -vf ...,rotate=R,...harddup ... R=旋转方式（0，逆时针90度。1，顺时针90度。）&lt;br /&gt;... -vf ...,mirror,...harddup ... 水平翻转&lt;br /&gt;... -vf ...flip,...harddup ... 垂直翻转&lt;br /&gt;.. .-vf ...,crop=W:H:X:Y,...harddup ...&lt;br /&gt;... -vf ...,expand=W:H:::1,...harddup ... 加黑边将画面扩展到W:H&lt;br /&gt;... -vf...-ofps F ... F=帧速率&lt;br /&gt;... -ss H:M:S:MS -endpos H:M:S:MS ... 时间分割（H=小时，M＝分钟，S＝秒，MS＝毫秒）&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//MP3音频控制&lt;br /&gt;-oac mp3lame -lameopts aq=Q:[mode=M:][vol=V:]cbr:br=B [-delay D] -srate H Q=精度，M=模式（3为单声道），V=音量，B=比特率，D=延迟，H=采样频率&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//字幕控制&lt;br /&gt;-sid [MKV字幕号] -sub [字幕文件路径] -font [字体文件路径] -subfont-text-scale [字体尺寸] -subfont-outline [字体边框尺寸（px）] -subfont-blur [字体模糊（%）] -subpos [字幕位置（%）] -subdelay [延迟] -subcp CP936 -unicode&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To PAL DVD&lt;br /&gt;&lt;br /&gt;mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:576,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9000:vbitrate=5001:keyint=15:vstrict=0:acodec=ac3:abitrate=224[:aspect=16/9|:aspect=4/3] -ofps 25 -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To NTSC DVD&lt;br /&gt;&lt;br /&gt;mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:480,harddup -srate 48000 -af lavcresample=48000 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9000:vbitrate=5001:keyint=18:vstrict=0:acodec=ac3:abitrate=224[:aspect=16/9|:aspect=4/3] -ofps 23.976 -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To PAL AVI Containing AC-3 Audio to DVD&lt;br /&gt;&lt;br /&gt;mencoder -oac copy -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf scale=720:576,harddup -ofps 25 -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9000:vbitrate=5001:keyint=15:vstrict=0[:aspect=16/9|:aspect=4/3] -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To NTSC AVI Containing AC-3 Audio to DVD&lt;br /&gt;&lt;br /&gt;mencoder -oac copy -ovc lavc -of mpeg -mpegopts format=dvd:tsaf:telecine -vf scale=720:480,harddup -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9000:vbitrate=5001:keyint=18:vstrict=0[:aspect=16/9|:aspect=4/3] -ofps 23.976 -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To PAL SVCD&lt;br /&gt;&lt;br /&gt;mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=xsvcd -vf scale=480:576,harddup -srate 44100 -af lavcresample=44100 -lavcopts vcodec=mpeg2video:mbd=2:keyint=15:vrc_buf_size=917:vrc_minrate=600:vbitrate=2001:vrc_maxrate=2500:acodec=mp2:abitrate=224 -ofps 25 -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;//To NTSC SVCD&lt;br /&gt;&lt;br /&gt;mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=xsvcd -vf scale=480:480,harddup -srate 44100 -af lavcresample=44100 -lavcopts vcodec=mpeg2video:mbd=2:keyint=18:vrc_buf_size=917:vrc_minrate=600:vbitrate=2001:vrc_maxrate=2500:acodec=mp2:abitrate=224 -ofps 23.976 -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To PAL VCD&lt;br /&gt;&lt;br /&gt;mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=xvcd -vf scale=352:288,harddup -srate 44100 -af lavcresample=44100 -lavcopts vcodec=mpeg1video:keyint=15:vrc_buf_size=327:vrc_minrate=1152:vbitrate=1152:vrc_maxrate=1152:acodec=mp2:abitrate=224 -ofps 25 -o OutputFile InputFile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//To NTSC VCD&lt;br /&gt;&lt;br /&gt;mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=xvcd -vf scale=352:240,harddup -srate 44100 -af lavcresample=44100 -lavcopts vcodec=mpeg1video:keyint=18:vrc_buf_size=327:vrc_minrate=1152:vbitrate=1152:vrc_maxrate=1152:acodec=mp2:abitrate=224 -ofps 23.976 -o OutputFile InputFile&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-52775690756105410?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/52775690756105410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=52775690756105410' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/52775690756105410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/52775690756105410'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2011/02/mencoder-commands.html' title='mencoder commands'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-4529063182901653652</id><published>2010-10-25T22:26:00.003+08:00</published><updated>2010-10-25T22:26:59.621+08:00</updated><title type='text'>comicchangeWithoutSizechange</title><content type='html'>#!/bin/bash - &lt;br /&gt;#===============================================================================&lt;br /&gt;#&lt;br /&gt;#          FILE:  compresszip.sh&lt;br /&gt;# &lt;br /&gt;#         USAGE:  ./compresszip.sh &lt;br /&gt;# &lt;br /&gt;#   DESCRIPTION:  for decompress the comic change the size and quality and compress it back&lt;br /&gt;# &lt;br /&gt;#       OPTIONS:  ---&lt;br /&gt;#  REQUIREMENTS:  ---&lt;br /&gt;#          BUGS:  ---&lt;br /&gt;#         NOTES:  ---&lt;br /&gt;#        AUTHOR: YOUR fullname (), &lt;br /&gt;#       COMPANY: &lt;br /&gt;#       CREATED: 08/26/2010 09:00:26 PM CST&lt;br /&gt;#      REVISION:  ---&lt;br /&gt;#===============================================================================&lt;br /&gt;&lt;br /&gt;set -o nounset                              # Treat unset variables as an error&lt;br /&gt;set -x&lt;br /&gt;&lt;br /&gt;#	[ "$#" -lt 2 ] &amp;&amp; echo "comicchange 80 comicfile" &amp;&amp; exit 4&lt;br /&gt;&lt;br /&gt;convert_zip_comic ()&lt;br /&gt;{&lt;br /&gt;	&lt;br /&gt;	if [ -d "$tmpfolder" ] ; then&lt;br /&gt;		#find $tmpfolder \( -iname \*jpg -o -iname \*png -o -iname tiff \) -exec convert -resize ${para}% -quality 80% "{}" "{}" \;&lt;br /&gt;		#zip -rqjm "$filename".zip $tmpfolder &amp;&amp; rm -rf $tmpfolder&lt;br /&gt;		cd $tmpfolder &amp;&amp; tar cf $workdir/"$filename".tar * &amp;&amp; cd $workdir &amp;&amp; rm -r $tmpfolder&lt;br /&gt;	fi&lt;br /&gt;&lt;br /&gt;}	# ----------  end of function decompress  ----------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;unzipcomic ()&lt;br /&gt;{&lt;br /&gt;	if [ -n "${fullname}" ] ; then&lt;br /&gt;		unzip -nLqa "$fullname" -d $tmpfolder &amp;&amp; rm "$fullname"&lt;br /&gt;	fi&lt;br /&gt;	&lt;br /&gt;}	# ----------  end of function unzipcomic  ----------&lt;br /&gt;&lt;br /&gt;unrarcomic ()&lt;br /&gt;{&lt;br /&gt;	if [ -n "${fullname}" ] ; then&lt;br /&gt;		mkdir "$tmpfolder" -p&lt;br /&gt;		unrar x -cl "$fullname" "$tmpfolder" &amp;&amp; rm  -rf "$fullname"&lt;br /&gt;	fi&lt;br /&gt;	&lt;br /&gt;}	# ----------  end of function unrarcomic  ----------&lt;br /&gt;&lt;br /&gt;untarcomic ()&lt;br /&gt;{&lt;br /&gt;	if [ -n "${fullname}" ] ; then&lt;br /&gt;		mkdir "$tmpfolder" -p&lt;br /&gt;		cd $tmpfolder; tar xpf $workdir/"$fullname"; cd $workdir; rm -rf "$fullname"&lt;br /&gt;	fi&lt;br /&gt;	&lt;br /&gt;}	# ----------  end of function unrarcomic  ----------&lt;br /&gt;&lt;br /&gt;check_origFile ()&lt;br /&gt;{&lt;br /&gt;	unzip -l tmp.zip | awk '{print $4}' | grep "\/$"&lt;br /&gt;}	# ----------  end of function check_origFile  ----------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;	&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;check_ext ()&lt;br /&gt;{&lt;br /&gt;	case $extname in&lt;br /&gt;		zip)&lt;br /&gt;			unzipcomic $fullname&lt;br /&gt;			;;&lt;br /&gt;&lt;br /&gt;		rar)&lt;br /&gt;			unrarcomic $fullname&lt;br /&gt;			;;&lt;br /&gt;&lt;br /&gt;		tar)&lt;br /&gt;			untarcomic $fullname&lt;br /&gt;			;;&lt;br /&gt;		*)&lt;br /&gt;			echo "file not found"&lt;br /&gt;			;;&lt;br /&gt;&lt;br /&gt;	esac    # --- end of case ---&lt;br /&gt;&lt;br /&gt;	#(([ "$extname" == "zip" ] &amp;&amp; unzipcomic $fullname) || ( [ "$extname" == "rar" ] &amp;&amp; unrarcomic $fullname )) || ([ "$extname" == "zip" ] &amp;&amp; unzipcomic $fullname) || echo "file not found"&lt;br /&gt;}	# ----------  end of function check_ext  ----------&lt;br /&gt;extname=""&lt;br /&gt;fullname=""&lt;br /&gt;filename=""&lt;br /&gt;tmpfolder=""&lt;br /&gt;#para=$1&lt;br /&gt;workdir=`pwd`&lt;br /&gt;extname="${*##*.}"&lt;br /&gt;filename="${*%%.*}"&lt;br /&gt;fullname=$*&lt;br /&gt;tmpfolder=/tmp/comicChange$RANDOM&lt;br /&gt;check_ext&lt;br /&gt;convert_zip_comic&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-4529063182901653652?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/4529063182901653652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=4529063182901653652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4529063182901653652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4529063182901653652'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/10/comicchangewithoutsizechange.html' title='comicchangeWithoutSizechange'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-2490368870523971753</id><published>2010-10-25T22:26:00.001+08:00</published><updated>2010-10-25T22:26:11.932+08:00</updated><title type='text'>comicchange</title><content type='html'>#!/bin/bash - &lt;br /&gt;#===============================================================================&lt;br /&gt;#&lt;br /&gt;#          FILE:  compresszip.sh&lt;br /&gt;# &lt;br /&gt;#         USAGE:  ./compresszip.sh &lt;br /&gt;# &lt;br /&gt;#   DESCRIPTION:  for decompress the comic change the size and quality and compress it back&lt;br /&gt;# &lt;br /&gt;#       OPTIONS:  ---&lt;br /&gt;#  REQUIREMENTS:  ---&lt;br /&gt;#          BUGS:  ---&lt;br /&gt;#         NOTES:  ---&lt;br /&gt;#        AUTHOR: YOUR fullname (), &lt;br /&gt;#       COMPANY: &lt;br /&gt;#       CREATED: 08/26/2010 09:00:26 PM CST&lt;br /&gt;#      REVISION:  ---&lt;br /&gt;#===============================================================================&lt;br /&gt;&lt;br /&gt;set -o nounset                              # Treat unset variables as an error&lt;br /&gt;set -x&lt;br /&gt;&lt;br /&gt;	[ "$#" -lt 2 ] &amp;&amp; echo "comicchange 80 comicfile" &amp;&amp; exit 4&lt;br /&gt;&lt;br /&gt;convert_zip_comic ()&lt;br /&gt;{&lt;br /&gt;	&lt;br /&gt;	if [ -d "$tmpfolder" ] ; then&lt;br /&gt;		find $tmpfolder \( -iname \*jpg -o -iname \*png -o -iname tiff \) -exec convert -resize ${para}% -quality 80% "{}" "{}" \;&lt;br /&gt;		#zip -rqjm "$filename".zip $tmpfolder &amp;&amp; rm -rf $tmpfolder&lt;br /&gt;		cd $tmpfolder &amp;&amp; tar cf $workdir/"$filename".tar * &amp;&amp; cd $workdir &amp;&amp; rm -r $tmpfolder&lt;br /&gt;	fi&lt;br /&gt;&lt;br /&gt;}	# ----------  end of function decompress  ----------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;unzipcomic ()&lt;br /&gt;{&lt;br /&gt;	if [ -n "${fullname}" ] ; then&lt;br /&gt;		unzip -nLqa "$fullname" -d $tmpfolder &amp;&amp; rm "$fullname"&lt;br /&gt;	fi&lt;br /&gt;	&lt;br /&gt;}	# ----------  end of function unzipcomic  ----------&lt;br /&gt;&lt;br /&gt;unrarcomic ()&lt;br /&gt;{&lt;br /&gt;	if [ -n "${fullname}" ] ; then&lt;br /&gt;		mkdir "$tmpfolder" -p&lt;br /&gt;		unrar x -cl "$fullname" "$tmpfolder" &amp;&amp; rm  -rf "$fullname"&lt;br /&gt;	fi&lt;br /&gt;	&lt;br /&gt;}	# ----------  end of function unrarcomic  ----------&lt;br /&gt;&lt;br /&gt;untarcomic ()&lt;br /&gt;{&lt;br /&gt;	if [ -n "${fullname}" ] ; then&lt;br /&gt;		mkdir "$tmpfolder" -p&lt;br /&gt;		cd $tmpfolder; tar xpf $workdir/"$fullname"; cd $workdir; rm -rf "$fullname"&lt;br /&gt;	fi&lt;br /&gt;	&lt;br /&gt;}	# ----------  end of function unrarcomic  ----------&lt;br /&gt;&lt;br /&gt;check_origFile ()&lt;br /&gt;{&lt;br /&gt;	unzip -l tmp.zip | awk '{print $4}' | grep "\/$"&lt;br /&gt;}	# ----------  end of function check_origFile  ----------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;	&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;check_ext ()&lt;br /&gt;{&lt;br /&gt;	case $extname in&lt;br /&gt;		zip)&lt;br /&gt;			unzipcomic $fullname&lt;br /&gt;			;;&lt;br /&gt;&lt;br /&gt;		rar)&lt;br /&gt;			unrarcomic $fullname&lt;br /&gt;			;;&lt;br /&gt;&lt;br /&gt;		tar)&lt;br /&gt;			untarcomic $fullname&lt;br /&gt;			;;&lt;br /&gt;		*)&lt;br /&gt;			echo "file not found"&lt;br /&gt;			;;&lt;br /&gt;&lt;br /&gt;	esac    # --- end of case ---&lt;br /&gt;&lt;br /&gt;	#(([ "$extname" == "zip" ] &amp;&amp; unzipcomic $fullname) || ( [ "$extname" == "rar" ] &amp;&amp; unrarcomic $fullname )) || ([ "$extname" == "zip" ] &amp;&amp; unzipcomic $fullname) || echo "file not found"&lt;br /&gt;}	# ----------  end of function check_ext  ----------&lt;br /&gt;extname=""&lt;br /&gt;fullname=""&lt;br /&gt;filename=""&lt;br /&gt;tmpfolder=""&lt;br /&gt;para=$1&lt;br /&gt;workdir=`pwd`&lt;br /&gt;extname="${2##*.}"&lt;br /&gt;filename="${2%%.*}"&lt;br /&gt;fullname=$2&lt;br /&gt;tmpfolder=/tmp/comicChange$RANDOM&lt;br /&gt;check_ext&lt;br /&gt;convert_zip_comic&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-2490368870523971753?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/2490368870523971753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=2490368870523971753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2490368870523971753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2490368870523971753'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/10/comicchange.html' title='comicchange'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-4573850462380587303</id><published>2010-09-19T00:17:00.001+08:00</published><updated>2010-09-19T00:17:18.939+08:00</updated><title type='text'>sshtunnel</title><content type='html'>#!/bin/bash - &lt;br /&gt;#===============================================================================&lt;br /&gt;#&lt;br /&gt;#          FILE:  sshtunnel.sh&lt;br /&gt;# &lt;br /&gt;#         USAGE:  ./sshtunnel.sh &lt;br /&gt;# &lt;br /&gt;#   DESCRIPTION:  for ssh link the blockcn file server.&lt;br /&gt;# &lt;br /&gt;#       OPTIONS:  ---&lt;br /&gt;#  REQUIREMENTS:  ---&lt;br /&gt;#          BUGS:  ---&lt;br /&gt;#         NOTES:  ---&lt;br /&gt;#        AUTHOR: kk (Kingkong Mok), kingkongmok@gmail.com&lt;br /&gt;#       COMPANY: &lt;br /&gt;#       CREATED: 09/18/2010 11:26:11 PM CST&lt;br /&gt;#      REVISION:  ---&lt;br /&gt;#===============================================================================&lt;br /&gt;&lt;br /&gt;set -o nounset                              # Treat unset variables as an error&lt;br /&gt;&lt;br /&gt;if [ `whoami` = root ] ; then&lt;br /&gt;	su kk -c "ssh -qTfnN -D 7070 kingkongmok@ssh201.blockcn.com"&lt;br /&gt;else&lt;br /&gt;	exit 3;&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-4573850462380587303?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/4573850462380587303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=4573850462380587303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4573850462380587303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4573850462380587303'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/sshtunnel_19.html' title='sshtunnel'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-1642683684859606276</id><published>2010-09-18T23:59:00.001+08:00</published><updated>2010-09-18T23:59:06.936+08:00</updated><title type='text'>wget</title><content type='html'>wget 使用技巧&lt;br /&gt;&lt;br /&gt;2007-10-14 Toy Posted in TipsRSSTrackback&lt;br /&gt;&lt;br /&gt;wget 是一个命令行的下载工具。对于我们这些 Linux 用户来说，几乎每天都在使用它。下面为大家介绍几个有用的 wget 小技巧，可以让你更加高效而灵活的使用 wget。&lt;br /&gt;&lt;br /&gt;    * $ wget -r -np -nd http://example.com/packages/&lt;br /&gt;&lt;br /&gt;这条命令可以下载 http://example.com 网站上 packages 目录中的所有文件。其中，-np 的作用是不遍历父目录，-nd 表示不在本机重新创建目录结构。&lt;br /&gt;&lt;br /&gt;    * $ wget -r -np -nd --accept=iso http://example.com/centos-5/i386/&lt;br /&gt;&lt;br /&gt;与上一条命令相似，但多加了一个 --accept=iso 选项，这指示 wget 仅下载 i386 目录中所有扩展名为 iso 的文件。你也可以指定多个扩展名，只需用逗号分隔即可。&lt;br /&gt;&lt;br /&gt;    * $ wget -i filename.txt&lt;br /&gt;&lt;br /&gt;此命令常用于批量下载的情形，把所有需要下载文件的地址放到 filename.txt 中，然后 wget 就会自动为你下载所有文件了。&lt;br /&gt;&lt;br /&gt;    * $ wget -c http://example.com/really-big-file.iso&lt;br /&gt;&lt;br /&gt;这里所指定的 -c 选项的作用为断点续传。&lt;br /&gt;&lt;br /&gt;    * $ wget -m -k (-H) http://www.example.com/&lt;br /&gt;&lt;br /&gt;该命令可用来镜像一个网站，wget 将对链接进行转换。如果网站中的图像是放在另外的站点，那么可以使用 -H 选项。&lt;br /&gt;&lt;br /&gt;============================================================================================&lt;br /&gt;&lt;br /&gt;转自http://linux.ccidnet.com/art/1101/20051128/628467_1.html&lt;br /&gt;&lt;br /&gt;A。使用wget工具&lt;br /&gt;&lt;br /&gt;linux所以的主要版本都自带了wget这个下载工具.&lt;br /&gt;&lt;br /&gt;bash$ wget http://place.your.url/here&lt;br /&gt;&lt;br /&gt;它还能控制ftp来下载整个web站点的各级目录,当然,如果你不小心,可能会把整个网站以及其他和他做链接的网站全部下载下来.&lt;br /&gt;&lt;br /&gt;bash$ wget -m http://target.web.site/subdirectory&lt;br /&gt;&lt;br /&gt;由于这个工具具有很将的下载能力,所以可以在服务器上把它用作镜像网站的工具.让它按照"robots.txt"的规定来执行.&lt;br /&gt;有很多参数用来控制它如何正确地做镜像,可以限制链接的类型和下载文件的类型等等.例如:只下载有联系的链接并且忽略GIF图片:&lt;br /&gt;&lt;br /&gt;bash$ wget -m -L --reject=gif http://target.web.site/subdirectory&lt;br /&gt;&lt;br /&gt;wget也能够实现端点续传(-c参数),当然,这种操作是需要远程服务器支持的.&lt;br /&gt;&lt;br /&gt;bash$ wget -c http://the.url.of/incomplete/file&lt;br /&gt;&lt;br /&gt;可以把端点续传和镜像功能结合起来,这样可以在以前断过多次的情况下继续镜像一个有大量选择性文件的站点.如何自动实现这个目的我们在后面会讨论得更多.&lt;br /&gt;如果你觉得下载时老是断线会影响你办公的话,你可以限制wget重试的次数.&lt;br /&gt;bash$ wget -t 5 http://place.your.url/here&lt;br /&gt;这样重试五次后就放弃了.用"-t inf"参数表示永远不放弃.不停地重试.&lt;br /&gt;&lt;br /&gt;B．那对于代理服务该怎么办呢?&lt;br /&gt;可以使用http代理的参数或者在.wgetrc配置文件里指定一个如何通过代理去下载的途径.但是有这么一个问题,&lt;br /&gt;如果通过代理来进行端点续传的话可能会有几次失败.如果有一次通过代理下载的过程发生中断,那么代理服务器上缓存里保存是那个完整的&lt;br /&gt;文件拷贝.所以当你用"wget -c"来下载剩余部分的时候代理服务器查看它的缓存,并错误地认为你已经下载了整个文件.于是就发出了错误的信号.&lt;br /&gt;这个时候你可以用添加一个特定的请求参数来促使代理服务器清除他们的缓存:&lt;br /&gt;&lt;br /&gt;bash$ wget -c --header="Pragma: no-cache" http://place.your.url/here&lt;br /&gt;&lt;br /&gt;这个"--header"参数能够以各种数字，各种方式添加。通过它我们可以更改&lt;br /&gt;web服务器或者代理服务器的某些属性。有些站点不提供外部连接的文件服务，只有通过同一个站点上其他的一些页面时内容&lt;br /&gt;才会被提交。这个时候你可以用加上"Referer:"&lt;br /&gt;参数：&lt;br /&gt;bash$ wget --header="Referer: http://coming.from.this/page" http://surfing.to.this/page&lt;br /&gt;有些特殊的网站只支持某种特定的浏览器，这个时候可以用"User-Agent:"参数&lt;br /&gt;bash$ wget --header="User-Agent: Mozilla/4.0 (compatible; MSIE 5.0;Windows NT; DigExt)" http://msie.only.url/here&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;C．那我怎么设定下载时间呢？&lt;br /&gt;如果你需要在你的办公电脑上通过和其他同事共享的一个连接来下载一些很大的文件，而且你希望你的同事不会因为网络速度的减慢而收到影响，&lt;br /&gt;那你就应该尽量避开高峰时段。当然,不需要在办公室里等到所以人都走掉，也不需要在家里用完晚饭后还惦记着要上网下载一次。&lt;br /&gt;用at来就可以很好的定制工作时间：&lt;br /&gt;bash$ at 2300&lt;br /&gt;warning: commands will be executed using /bin/sh&lt;br /&gt;at&gt; wget http://place.your.url/here&lt;br /&gt;at&gt; press Ctrl-D&lt;br /&gt;这样，我们设定了下载工作在晚上11点进行。为了使这个安排能够正常进行，请确&lt;br /&gt;认atd这个后台程序正在运行。&lt;br /&gt;&lt;br /&gt;D．下载要花很多时间？&lt;br /&gt;当你需要下载大量的数据，而且你又没有享有足够的带宽,这个时候你会经常发现在你安排的下载任务还没有完成，一天的工作却又要开始了。&lt;br /&gt;作为一个好同事，你只能停掉了这些任务，而开始另外的工作。然后你又需要反复地重复使用"wget -c"来完成你的下载。这样肯定太繁琐了，&lt;br /&gt;所以最好是用crontab来自动执行。创建一个纯文本文件，叫做"crontab.txt",包含下面的内容：&lt;br /&gt;0 23 * * 1-5 wget -c -N http://place.your.url/here&lt;br /&gt;0 6 * * 1-5 killall wget&lt;br /&gt;这个crontab文件指定某些任务定期地执行。前五列声明是什么时候执行这个命令，而每行的剩余部分则告诉crontab执行什么内容。&lt;br /&gt;前两列指定了每天一到晚上11点就开始用wget下载，一到早上6点就停止一切wget&lt;br /&gt;下载。第三四列的*表示每个月的每一天都执行这个任务。第五列则指定了一个星期的哪几天来执行这个程序。 --"1-5"表示从星期一&lt;br /&gt;到星期五。&lt;br /&gt;&lt;br /&gt;这样在每个工作日的晚上11点，下载工作开始，到了上午的6点，任何的wget任务&lt;br /&gt;就被停掉了。你可以用下面的命令来执行crontab：&lt;br /&gt;bash$ crontab crontab.txt&lt;br /&gt;wget的这个"-N"参数将会检查目标文件的时间戳，如果匹配了，下载程序就会停止，因为它说明整个文件已经下载完全了。&lt;br /&gt;用"crontab -r"可以删除这个计划安排。我已经多次采用这种方法，通过共享的电话拨号来下载过很多的ISO镜像文件,还是&lt;br /&gt;比较实用的。&lt;br /&gt;&lt;br /&gt;E．如何下载动态变化的网页&lt;br /&gt;有些网页每天都要根据要求变化好几次.所以从技术上讲,目标不再是一个文件,它没有文件长度.因此"-c"这个参数也就失去了意义.&lt;br /&gt;例如:一个PHP写的并且经常变动的linux周末新闻网页:&lt;br /&gt;bash$ wget http://lwn.net/bigpage.php3&lt;br /&gt;&lt;br /&gt;我办公室里的网络条件经常很差,给我的下载带了很大的麻烦,所以我写了个简单的脚本来检测动态页面是否已经完全更新了.&lt;br /&gt;#!/bin/bash&lt;br /&gt;&lt;br /&gt;#create it if absent&lt;br /&gt;touch bigpage.php3&lt;br /&gt;&lt;br /&gt;#check if we got the whole thing&lt;br /&gt;while ! grep -qi bigpage.php3&lt;br /&gt;do&lt;br /&gt;rm -f bigpage.php3&lt;br /&gt;&lt;br /&gt;#download LWN in one big page&lt;br /&gt;wget http://lwn.net/bigpage.php3&lt;br /&gt;&lt;br /&gt;done&lt;br /&gt;这个脚本能够保证持续的下载该网页,直到网页里面出现了"",这就表示该文件已经完全更新了.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;F．对于ssl和Cookies怎么办？&lt;br /&gt;如果你要通过ssl来上网,那么网站地址应该是以"https://"来开头的.在这样的情况下你就需要另外一种下载工具,叫做curl，它能够&lt;br /&gt;很容易获得.有些网站迫使网友在浏览的时候必须使用cookie.所以你必须从在网站上得到的那个Cookie里面得到"Cookie:"这个参数.这样才&lt;br /&gt;能保证下载的参数正确.对于lynx和Mozilla的Cookie的文件格式,用下面的:&lt;br /&gt;bash$ cookie=$( grep nytimes ~/.lynx_cookies |awk {printf("%s=%s;",$6,$7)} )&lt;br /&gt;就可以构造一个请求Cookie来下载http://www.nytimes.com上的内容.当然,你要已经用这个浏览器在该网站上完成注册.&lt;br /&gt;w3m使用了一种不同的,更小巧的Cookie文件格式:&lt;br /&gt;bash$ cookie=$( grep nytimes ~/.w3m/cookie |awk {printf("%s=%s;",$2,$3)} )&lt;br /&gt;现在就可以用这种方法来下载了:&lt;br /&gt;bash$ wget --header="Cookie: $cookie" http://www.nytimes.com/reuters/technology/tech-tech-supercomput.html&lt;br /&gt;或者用curl工具:&lt;br /&gt;bash$ curl -v -b $cookie -o supercomp.html http://www.nytimes.com/reuters/technology/tech-tech-supercomput.htm&lt;br /&gt;&lt;br /&gt;G．如何建立地址列表？&lt;br /&gt;到现在为止我们下载的都是单个文件或者是整个网站.有的时候我们需要下载某个网页上链接的大量文件,但没有必要把它整个网站&lt;br /&gt;都镜像下来.比如说我们想从一个依次排列的100首歌里面下载前20首.注意,这里"--accept"和"--reject"参数是不会&lt;br /&gt;起作用的,因为他们只对文件操作起作用.所以一定要用"lynx -dump"参数来代替.&lt;br /&gt;bash$ lynx -dump ftp://ftp.ssc.com/pub/lg/ |grep gz$ |tail -10 |awk {print $2} &gt; urllist.txt&lt;br /&gt;lynx的输出结果可以被各种GNU文本处理工具过虑.在上面的例子里,我们的链接地址是以"gz"结尾的,并且把最后10个文件地址放到&lt;br /&gt;urllist.txt文件里.然后我们可以写一个简单的bash脚本来自动下载这个文件里的目标文件:&lt;br /&gt;&lt;br /&gt;bash$ for x in $(cat urllist.txt)&lt;br /&gt;&gt; do&lt;br /&gt;&gt; wget $x&lt;br /&gt;&gt; done&lt;br /&gt;这样我们就能够成功下载Linux Gazette网站(ftp://ftp.ssc.com/pub/lg/)上的最新10个论题.&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;H．扩大使用的带宽&lt;br /&gt;如果你选择下载一个受带宽限制的文件,那你的下载会因为服务器端的限制而变得很慢.下面这个技巧会大大缩短下载的过程.但这个技巧&lt;br /&gt;需要你使用curl并且远程服务器有多个镜像可以供你下载.例如,假设你想从下面的三个地址下载Mandrake 8.0:&lt;br /&gt;url1=http://ftp.eecs.umich.edu/pub/linux/mandrake/iso/Mandrake80-inst.iso&lt;br /&gt;url2=http://ftp.rpmfind.net/linux/Mandrake/iso/Mandrake80-inst.iso&lt;br /&gt;url3=http://ftp.wayne.edu/linux/mandrake/iso/Mandrake80-inst.iso&lt;br /&gt;这个文件的长度是677281792个字节,所以用curl程序加"--range"参数来建立三个同时进行的下载:&lt;br /&gt;bash$ curl -r 0-199999999 -o mdk-iso.part1 $url1 &amp;&lt;br /&gt;bash$ curl -r 200000000-399999999 -o mdk-iso.part2 $url2 &amp;&lt;br /&gt;bash$ curl -r 400000000- -o mdk-iso.part3 $url3 &amp;&lt;br /&gt;这样就创建了三个后台进程.每个进程从不同的服务器传输这个ISO文件的不同部分.这个"-r"参数指定目标文件的字节范围.当这三个&lt;br /&gt;进程结束后,用一个简单的cat命令来把这三个文件衔接起来-- cat mdk-iso.part? &gt; mdk-80.iso.(强烈建议在刻盘之前先检查md5)&lt;br /&gt;你也可以用"--verbose"参数来使每个curl进程都有自己的窗口来显示传输的过程.&lt;br /&gt;&lt;br /&gt;结束语&lt;br /&gt;不用担心使用非交互式的下载方式会影响你的下载效果.无论网站设计者如何绞尽脑汁想阻止我们从他们的网站下载,我们都可以得到&lt;br /&gt;免费的工具来自动完成下载任务.这会大大丰富我们的网络经历. &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-1642683684859606276?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/1642683684859606276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=1642683684859606276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1642683684859606276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1642683684859606276'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/wget_18.html' title='wget'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-2061610972338369608</id><published>2010-09-17T20:19:00.001+08:00</published><updated>2010-09-17T20:19:02.987+08:00</updated><title type='text'>pick_by_random</title><content type='html'>#!/bin/bash - &lt;br /&gt;#===============================================================================&lt;br /&gt;#&lt;br /&gt;#          FILE: &lt;br /&gt;# &lt;br /&gt;#         USAGE:  &lt;br /&gt;# &lt;br /&gt;#   DESCRIPTION:  pick up a parameter arguments for ${array[@]}&lt;br /&gt;# &lt;br /&gt;#       OPTIONS:  ---&lt;br /&gt;#  REQUIREMENTS:  ---&lt;br /&gt;#          BUGS:  ---&lt;br /&gt;#         NOTES:  ---&lt;br /&gt;#        AUTHOR: kk (kingkongmok@grail.com), &lt;br /&gt;#       COMPANY: &lt;br /&gt;#       CREATED: 09/14/2010 03:57:51 PM CST&lt;br /&gt;#      REVISION:  ---&lt;br /&gt;#===============================================================================&lt;br /&gt;&lt;br /&gt;set -o nounset                              # Treat unset variables as an error&lt;br /&gt;&lt;br /&gt;arrays=($@)&lt;br /&gt;NUMB=${#arrays[@]}&lt;br /&gt;echo "$NUMB"&lt;br /&gt;&lt;br /&gt;while true ; do&lt;br /&gt;	read kick;&lt;br /&gt;&lt;br /&gt;RANDOMNUMB=$((RANDOM%$NUMB))&lt;br /&gt;echo "$RANDOMNUMB"&lt;br /&gt;echo "it's ${arrays[RANDOMNUMB]}"&lt;br /&gt;done&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-2061610972338369608?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/2061610972338369608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=2061610972338369608' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2061610972338369608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2061610972338369608'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/pickbyrandom.html' title='pick_by_random'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-3764358838949292526</id><published>2010-09-17T20:16:00.003+08:00</published><updated>2010-09-17T20:16:50.885+08:00</updated><title type='text'>lockcomputer</title><content type='html'>#!/bin/bash - &lt;br /&gt;#===============================================================================&lt;br /&gt;#&lt;br /&gt;#          FILE:  lockcomputer.sh&lt;br /&gt;# &lt;br /&gt;#         USAGE:  ./lockcomputer.sh &lt;br /&gt;# &lt;br /&gt;#   DESCRIPTION:  lock the computer with screensaver and turn off the dpms&lt;br /&gt;# &lt;br /&gt;#       OPTIONS:  ---&lt;br /&gt;#  REQUIREMENTS:  ---&lt;br /&gt;#          BUGS:  ---&lt;br /&gt;#         NOTES:  ---&lt;br /&gt;#        AUTHOR: kk (kingkongmok@gmail.com), &lt;br /&gt;#       COMPANY: &lt;br /&gt;#       CREATED: 09/03/2010 05:17:53 PM CST&lt;br /&gt;#      REVISION:  ---&lt;br /&gt;#===============================================================================&lt;br /&gt;&lt;br /&gt;set -o nounset                              # Treat unset variables as an error&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;gnome-screensaver-command -l &lt;br /&gt;while true ; do xset dpms force off ; sleep 10; done&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-3764358838949292526?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/3764358838949292526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=3764358838949292526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3764358838949292526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3764358838949292526'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/lockcomputer.html' title='lockcomputer'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-2415903369878856101</id><published>2010-09-17T20:16:00.001+08:00</published><updated>2010-09-17T20:16:37.534+08:00</updated><title type='text'>voa_online</title><content type='html'>#!/bin/bash&lt;br /&gt;&lt;br /&gt;while true ; do&lt;br /&gt;	mplayer -cache 100 rtsp://a1702.l211048984.c2110.g.lr.akamaistream.net:554/live/D/1702/2110/v0001/reflector:48984;&lt;br /&gt;	sleep 2;&lt;br /&gt;done&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-2415903369878856101?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/2415903369878856101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=2415903369878856101' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2415903369878856101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2415903369878856101'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/voaonline.html' title='voa_online'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-947848834039409277</id><published>2010-09-17T20:15:00.001+08:00</published><updated>2010-09-17T20:15:00.837+08:00</updated><title type='text'>change_name</title><content type='html'>#!/bin/bash - &lt;br /&gt;#===============================================================================&lt;br /&gt;#&lt;br /&gt;#          FILE:  change_name.sh&lt;br /&gt;# &lt;br /&gt;#         USAGE:  ./change_name.sh &lt;br /&gt;# &lt;br /&gt;#   DESCRIPTION:  for change files name.&lt;br /&gt;# &lt;br /&gt;#       OPTIONS:  ---&lt;br /&gt;#  REQUIREMENTS:  ---&lt;br /&gt;#          BUGS:  ---&lt;br /&gt;#         NOTES:  ---&lt;br /&gt;#        AUTHOR: kk (kingkongmok@gmail.com), &lt;br /&gt;#       COMPANY: &lt;br /&gt;#       CREATED: 09/17/2010 08:48:39 AM CST&lt;br /&gt;#      REVISION:  ---&lt;br /&gt;#===============================================================================&lt;br /&gt;&lt;br /&gt;set -o nounset                              # Treat unset variables as an error&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;WORKDIRECTORY=""&lt;br /&gt;if [ $# -lt 1 ] ; then&lt;br /&gt;	WORKDIRECTORY=`pwd`&lt;br /&gt;	else&lt;br /&gt;	if [ -n $1 ] ; then&lt;br /&gt;		if [ -d $1 ]; then&lt;br /&gt;		WORKDIRECTORY=$1&lt;br /&gt;		else&lt;br /&gt;		echo "$1 not exists"&lt;br /&gt;		fi&lt;br /&gt;	fi&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;FILES=""&lt;br /&gt;FILES=($WORKDIRECTORY/*)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;echo "WORKDIRECTORY is ${WORKDIRECTORY}"&lt;br /&gt;&lt;br /&gt;echo "files' numb is ${#FILES[@]}"&lt;br /&gt;NUMB=${#FILES[@]}&lt;br /&gt;FILES_LENGTH=${#NUMB}&lt;br /&gt;echo "the file numb's digit length is ${FILES_LENGTH}"&lt;br /&gt;FILES_ITERATOR=""&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;for (( FILES_ITERATOR=0; FILES_ITERATOR&lt;${#FILES[@]}; FILES_ITERATOR+=1 )); do&lt;br /&gt;	FILE_ITERATOR_LENGTH_TEMP=$((FILES_ITERATOR+1))&lt;br /&gt;	FILES_ITERATOR_LENGTH=${#FILE_ITERATOR_LENGTH_TEMP}&lt;br /&gt;	echo "FILES_ITERATOR_LENGTH is $FILES_ITERATOR_LENGTH"&lt;br /&gt;	ZERO_NUMB=$(( $((FILES_LENGTH)) - $((FILES_ITERATOR_LENGTH)) ))&lt;br /&gt;	for (( CNTR=0; CNTR&lt;$ZERO_NUMB; CNTR+=1 )); do&lt;br /&gt;		echo -n "0"&lt;br /&gt;	done&lt;br /&gt;	echo "$((FILES_ITERATOR+1))${FILES[FILES_ITERATOR]##*/}	"&lt;br /&gt;	echo &lt;br /&gt;done&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-947848834039409277?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/947848834039409277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=947848834039409277' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/947848834039409277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/947848834039409277'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/changename.html' title='change_name'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-8900472844229246292</id><published>2010-09-11T11:06:00.001+08:00</published><updated>2010-09-11T11:06:02.580+08:00</updated><title type='text'>最牛bash</title><content type='html'>注转载来自于 http://www.isspy.com/most_useful_linux_commands_1/的”最牛B的 Linux Shell 命令系列连载”文章。&lt;br /&gt;个人认为作为 Linux 用户，熟练掌握 CLI 命令是一个比较基本的能力，而这篇连载文章提供了更深层次的内容，可以帮助大家学习到更多有用的内容。&lt;br /&gt;&lt;br /&gt;编者按&lt;br /&gt;&lt;br /&gt;本文编译自commandlinefu.com ( 应该是 Catonmat ) 的系列文章 Top Ten One-Liners from CommandLineFu Explained 。作为一个由用户推荐最有用shell命令的网站，其记录了数以万计的各色shell命令，其中不乏相当实用和有趣的，本文就要细数当中获投票最高的一些命令，从其中取材并加以细释，希望读者能从中受益。&lt;br /&gt;&lt;br /&gt;引言&lt;br /&gt;&lt;br /&gt;Shell作为Unix系操作系统当中最有魅力且不可或缺的组件，经过数十载的洗礼不仅没有被淘汰，而且愈加变得成熟稳健，究其原因，大概因为它是个非常稳固的粘合剂，能够把大量功能强大的组件任意配搭，总能很好很快地完成用户的任务。&lt;br /&gt;&lt;br /&gt;本文的一些命令很可能看起来是”雕虫小技”，我们只好仰慕一下Shell大牛了，但是有些细节我会稍加发掘加以说明，遇到有趣的地方希望能博您一笑了。&lt;br /&gt;&lt;br /&gt;1.以SUDO运行上条命令&lt;br /&gt;&lt;br /&gt;$ sudo !!&lt;br /&gt;&lt;br /&gt;大家应该都知sudo，不解释。但通常出现的情况是，敲完命令执行后报错才发现忘了sudo。这时候，新手用户就会：按上箭头，按左箭头，盯着光标回到开始处，输入sudo，回车；高手用户就蛋定多了，按Ctrl-p，按Ctrl-a，输入sudo，回车。&lt;br /&gt;这里介绍这个是天外飞仙级别的，对，就直接sudo !!。&lt;br /&gt;当然这几种解决方式效果是完全一样的，只是款不一样，嗯，不解释。&lt;br /&gt;两个感叹号其实是bash的一个特性，称为事件引用符（event designators）。!!其实相当于!-1，引用前一条命令，当然也可以!-2，!-50。默认情况下bash会在~/.bash_history 文件内记录用户执行的最近500条命令，history命令可以显示这些命令。&lt;br /&gt;关于事件引用符的更多用法可以深入阅读 The Definitive Guide to Bash Command Line History。&lt;br /&gt;&lt;br /&gt;2.以HTTP方式共享当前文件夹的文件&lt;br /&gt;&lt;br /&gt;$ python -m SimpleHTTPServer&lt;br /&gt;&lt;br /&gt;这命令启动了Python的SimpleHTTPServer模块，考虑到Python在绝大多数的Linux发行版当中都默认安装，所以这个命令很可能是最简单的跨平台传文件的方法。&lt;br /&gt;命令执行后将在本机8000端口开放HTTP服务，在其他能访问本机的机器的浏览器打开ttp://ip:8000即打开一个目录列表，点击即可下载。&lt;br /&gt;&lt;br /&gt;3.在以普通用户打开的VIM当中保存一个ROOT用户文件&lt;br /&gt;&lt;br /&gt;:w !sudo tee %&lt;br /&gt;&lt;br /&gt;这题目读起来纠结，其实是很常见的，常常忘记了sudo就直接用vim编辑/etc内的文件，（不过也不一定，vim发现保存的文件无法保存时候会提示）等编辑好了，保存时候才发现没权限。曲线方法是先保存个临时文件，退出后再sudo cp回去。不过实际上在vim里面可以直接完成这个过程的，命令就是如此。&lt;br /&gt;查阅vim的文档（输入:help :w），会提到命令:w!{cmd}，让vim执行一个外部命令{cmd}，然后把当前缓冲区的内容从stdin传入。&lt;br /&gt;tee是一个把stdin保存到文件的小工具。&lt;br /&gt;而%，是vim当中一个只读寄存器的名字，总保存着当前编辑文件的文件路径。&lt;br /&gt;所以执行这个命令，就相当于从vim外部修改了当前编辑的文件，好完工。&lt;br /&gt;&lt;br /&gt;4.切换回上一个目录&lt;br /&gt;&lt;br /&gt;$ cd -&lt;br /&gt;&lt;br /&gt;应该不少人都知道这个，横杆-代表上一个目录的路径。&lt;br /&gt;实际上cd -就是cd $OLDPWD的简写，bash的固定变量$OLDPWD总保存着之前一个目录的路径。&lt;br /&gt;相对地，$PWD总保存着当前目录的路径。这些变量在编写shell脚本时候相当有用。&lt;br /&gt;&lt;br /&gt;5.替换上一条命令中的一个短语&lt;br /&gt;&lt;br /&gt;$ ^foo^bar^&lt;br /&gt;&lt;br /&gt;又是另外一个事件引用符（event designator），可以把上一条命令当中的foo替换成bar。&lt;br /&gt;在需要重复运行调试一道长长的命令，需要测试某个参数时候，用这个命令会比较实用；但多数人会首先选择按上箭头提出上道命令，再移动光标去修改某参数，这样更直观，但效率上就不够使用引用符高，而且在脚本中用这个方法可以简化很多。&lt;br /&gt;这道命令的原始样式应该是这样的:&lt;br /&gt;&lt;br /&gt;!!:s/foo/bar/&lt;br /&gt;&lt;br /&gt;本文一开始介绍过!!，后面的一段大家应该很熟悉，vim、sed的替换操作都是这样的语法。&lt;br /&gt;&lt;br /&gt;关于事件引用符的更多用法可以深入阅读The Definitive Guide to Bash Command Line History&lt;br /&gt;&lt;br /&gt;6.快速备份一个文件&lt;br /&gt;&lt;br /&gt;$ cp filename{,.bak}&lt;br /&gt;&lt;br /&gt;这道命令把filename文件拷贝成filename.bak，大家应该在一些比较复杂的安装教程里面见过这样的用法。其原理就在于bash对大括号的展开操作，filename{,.bak}这一段会被展开成filename filename.bak再传给cp，于是就有了备份的命令了。&lt;br /&gt;&lt;br /&gt;大括号在bash里面是一个排列的意义，可以试试这个&lt;br /&gt;&lt;br /&gt;$ echo {a,b,c}{a,b,c}{a,b,c}&lt;br /&gt;&lt;br /&gt;将输出三个集合的全排列:&lt;br /&gt;&lt;br /&gt;aaa aab aac aba abb abc aca acb acc&lt;br /&gt;baa bab bac bba bbb bbc bca bcb bcc&lt;br /&gt;caa cab cac cba cbb cbc cca ccb ccc&lt;br /&gt;关于shell当中的集合操作，可深入阅读”Set Operations in the Unix Shell”&lt;br /&gt;&lt;br /&gt;7.免密码SSH登录主机&lt;br /&gt;&lt;br /&gt;$ ssh-copy-id remote-machine&lt;br /&gt;&lt;br /&gt;这个命令把当前用户的公钥串写入到远程主机的~/.ssh/authorized_keys内，这样下次使用ssh登录的时候，远程主机就直接根据这串密钥完成身份校验，不再询问密码了。前提是你当前用户有生成了公钥，默认是没有的，先执行ssh-keygen试试吧！&lt;br /&gt;这个命令如果用手工完成，是这样的&lt;br /&gt;&lt;br /&gt;your-machine$ scp ~/.ssh/identity.pub remote-machine:&lt;br /&gt;your-machine$ ssh remote-machine&lt;br /&gt;remote-machine$ cat identity.pub &gt;&gt; ~/.ssh/authorized_keys&lt;br /&gt;&lt;br /&gt;如果你想删掉远程主机上的密钥，直接打开authorized_keys，搜索你的用户名，删除那行，即可。&lt;br /&gt;&lt;br /&gt;8.抓取LINUX桌面的视频&lt;br /&gt;&lt;br /&gt;$ ffmpeg -f x11grab -s wxga -r 25 -i :0.0 -sameq /tmp/out.mpg&lt;br /&gt;&lt;br /&gt;我们在一些视频网站上看到别人的3D桌面怎么怎么酷的视频，通常就是这么来的，ffmpeg可以直接解码X11的图形，并转换到相应输出格式。&lt;br /&gt;ffmpeg的通常用法是，根据一堆参数，输出一个文件，输出文件通常放最后，下面解析下几个参数：&lt;br /&gt;-f x11grab 指定输入类型。因为x11的缓冲区不是普通的视频文件可以侦测格式，必须指定后ffmpeg才知道如何获得输入。&lt;br /&gt;-s wxga 设置抓取区域的大小。wxga是1366*768的标准说法，也可以换成-s 800×600的写法。&lt;br /&gt;-r 25 设置帧率，即每秒抓取的画面数。&lt;br /&gt;-i :0.0 设置输入源，本地X默认在0.0&lt;br /&gt;-sameq 保持跟输入流一样的图像质量，以用来后期处理。&lt;br /&gt;至于其他ffmpeg的用法，可以参考下面两篇文章：&lt;br /&gt;&lt;br /&gt;How to Extract Audio Tracks from YouTube Videos&lt;br /&gt;Converting YouTube Flash Videos to a Better Format with ffmpeg&lt;br /&gt;&lt;br /&gt;后记&lt;br /&gt;&lt;br /&gt;说 Shell是一种编程语言，可能有些尴尬，虽然很多人每天都在用Shell，但从来没见它荣登TIOBE编程语言排行榜之类的，可以说毫无名分，因为很多用户没意识到它是一种语言，只当做这是一个能够很好完成任务的工具，基本得理所当然，就好像GUI程序的菜单、按钮一样。&lt;br /&gt;&lt;br /&gt;掌握 Shell，通常能够让任务在数秒钟内完成，这就让Shell跟C、Perl、Python这些语言区别开来，没人否认后者更能胜任更多的任务，但是他们是在不同的层面上去做，Shell依赖大量的系统组件黏合调用，而后者依赖各种库，各所擅长不同的应用领域，比喻就是，Shell是混凝土，可以很方便地粘合一些建筑组件而成为稳固的高楼大厦；但同样是粘合剂，粘玻璃窗、粘书报、粘皮鞋，混凝土是绝对不合适的，Shell并不擅长一些细致操作，比如它连浮点运算都不支持，更别提什么图形运算什么的。但这并不妨碍Shell来帮我们完成很多粗重任务。&lt;br /&gt;&lt;br /&gt;Shell的工作方式，大多数入门用户会觉得枯燥难学，而所谓的经典教材也离不开《Advanced Bash-Scripting》、《Bash Guide for Beginners》，但类似本文这样的一些”雕虫小技”因为难登大雅之堂绝不会收录进去。这情况如果象国外一些unix用户比较多的地方会有很好改善，即使是新手，偶尔看看别人的操作都能”偷师”一手，我编译本系列文章其实也就希望稍微改善一下这个状况。&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-8900472844229246292?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/8900472844229246292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=8900472844229246292' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8900472844229246292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8900472844229246292'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/bash.html' title='最牛bash'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-5520452739777556792</id><published>2010-09-09T23:52:00.001+08:00</published><updated>2010-09-09T23:52:08.467+08:00</updated><title type='text'>qemu</title><content type='html'>http://www.crazysquirrel.com/computing/debian/applications/xp-under-debian-with-qemu.jspx&lt;br /&gt;QEMU&lt;br /&gt;&lt;br /&gt;QEMU is a fairly complete x86 emulator that lets you run one operating system under another. Currently it is best supported under Linux where it can host numerous other OSes. This guide looks are running Windows XP under QEMU on Debian Linux. Note: although Debian is free you must have a license for the copy of Windows XP you will be running.&lt;br /&gt;Installing QEMU&lt;br /&gt;&lt;br /&gt;the first thing to do is install QEMU. Simply use apt-get or any one of the other package managers around.&lt;br /&gt;&lt;br /&gt;apt-get -u install qemu&lt;br /&gt;&lt;br /&gt;Create a Virtual Hard Disk&lt;br /&gt;&lt;br /&gt;QEMU uses a large file rather than a real partition to run the guest perating system. This means that it is very easy to create multiple guest systems on the same machine. I have chosen to install Windows XP under /var/qemu for two reasons. Firstly, my home directory is NFS shared off a server - QEMU is quite slow when performing disk access and the network delays would make this worse. Secondly, my home directory is backed up nightly and I don't want to place an undue load on the back up. Apart from these two reasons I would have created the file in my home directory.&lt;br /&gt;&lt;br /&gt;The command below will create a file of around 3.5 GB which should be ample for XP + SP2 and a few applications. Note that you won't be working on XP under QEMU. While it's useable it is to slow to work on. I use this set up mainly to check websites in IE.&lt;br /&gt;&lt;br /&gt;cd /var/qemu&lt;br /&gt;dd of=xp.img bs=1024 seek=3500000 count=0&lt;br /&gt;0+0 records in&lt;br /&gt;0+0 records out&lt;br /&gt;0 bytes transferred in 1*10-9 seconds (0 bytes/sec)&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;qemu-img xp.img 3.5G&lt;br /&gt;&lt;br /&gt;I used the first version but a fair number of people claim the second is better. The main reason given is that dd will allocate the whole 3.5GB in one shot wasting space on the drive. This is actually not the case because of the use of the seek argument. I don't think there is any real difference betwen the two commands.&lt;br /&gt;Install XP&lt;br /&gt;&lt;br /&gt;Now that the virtual drive has been created it's time to install XP on it. The command below tells QEMU to boot from the "d" drive and use the /dev/cdrom device as the cdrom and the virtual drive as the first hard disk (hda). Place the XP install cd in /dev/cdrom and start QEMU. You should see a new window pop up and display the XP install sequence.&lt;br /&gt;&lt;br /&gt;qemu -boot d -cdrom /dev/cdrom -hda xp.img&lt;br /&gt;QEMU 0.6.0 monitor - type 'help' for more information&lt;br /&gt;&lt;br /&gt;Wait...&lt;br /&gt;&lt;br /&gt;Wait. Then wait some more while the XP install process takes place. For some reason it takes hours even on a very fast machine. Many people have pointed this out but no one seems to know why. After the install was complete my copy of XP hung on the first boot (no progress and no CPU useage). This has been reported by some people who have waited more than a day for the system to boot with no effect. I got fed up of waiting and shut the virtual machine down and restarted it. I have had this happen with real XP installs as well so I can only assume there is a bug.&lt;br /&gt;Image Backups&lt;br /&gt;&lt;br /&gt;Nows quite a good time to take a back up of the install. If something goes wrong you can then simply copy the backup over the dead version and have a fresh install.&lt;br /&gt;&lt;br /&gt;cp xp.img clean-xp.img&lt;br /&gt;&lt;br /&gt;Set up the Vitrual Network&lt;br /&gt;&lt;br /&gt;In order to talk to the outside world you need to set up a virtual network card for QEMU. By default it will try and use tun. The tun device on Debian can't be accessed to by anyone but root by default which isn't very helpful so use the following commands to change that. The first two change permissions the last two load the tun module into the kernel so that tun actually works. Note that the group used here is staff. It might be users on your system.&lt;br /&gt;&lt;br /&gt;chgrp staff /dev/net/tun &lt;br /&gt;chmod g+rw /dev/net/tun&lt;br /&gt;modprobe tun&lt;br /&gt;echo 'tun' &gt;&gt; /etc/modules&lt;br /&gt;&lt;br /&gt;I found that the group setting on the tun device was reset after a reboot but the permissions weren't. To get round this I set the permissions to 666 (rw for everyone) on the run device. Your mileage may vary of course.&lt;br /&gt;&lt;br /&gt;chmod 666 /dev/net/tun&lt;br /&gt;&lt;br /&gt;QEMU tries to run the /etc/qemu-ifup script with uses /sbin/ifconfig when it starts a virtual machine. In order to run this you need to give the user running the script the ability to execute ifconfig. This is done using sudo. A very basic example sudo file is shown below.&lt;br /&gt;&lt;br /&gt;# Cmnd alias specification&lt;br /&gt;Cmnd_Alias QEMU=/sbin/ifconfig&lt;br /&gt;&lt;br /&gt;# User privilege specification&lt;br /&gt;root            ALL=(ALL) ALL&lt;br /&gt;%staff          ALL=NOPASSWD: QEMU&lt;br /&gt;&lt;br /&gt;Note that the default Debain install of QEMU puts the tun device on 172.20.0.1 which means XP should be put on 172.20.0.2 and use 172.20.0.1 as a gateway. If your network doesn't use this block of non-routable addresses it might be worth your time changing this so that the guest OS is in your locak network IP space. I quite like it like this as it makes the virtual machine easy to seperate out on the network.&lt;br /&gt;&lt;br /&gt;Once the settings in XP are correct you should be able to ping back and forth between host and guest machine. Setting it up so that the guest can access the Internet is a little harder and I will come to that later. If the machines can't talk to each other make sure that there isn't a firewall blocking communication. XP with SP2 has the firewall switched on by default and my Linux box blocked all non-local traffic.&lt;br /&gt;Boot XP&lt;br /&gt;&lt;br /&gt;Now it's time to boot XP. The following command should do it.&lt;br /&gt;&lt;br /&gt;qemu -hda xp.img -boot c&lt;br /&gt;&lt;br /&gt;I hit a bit of a snag at this point. When I tried to log in I got a message about not being able to activate Windows. Reading around I found out that this is something to do with the virtual network device. The solution, which requires some sneakyness, is given below.&lt;br /&gt;Error code 0x800703e6 on Product Activation - Installing Service Pack 2&lt;br /&gt;&lt;br /&gt;Download Windows XP Service Pack 2 while this is a big download it does mean that you won't need to use the network to install it.&lt;br /&gt;&lt;br /&gt;Create an iso image of the file with "mkisofs -o sp2.iso &lt;name-of-sp2-file.exe&gt;"&lt;br /&gt;&lt;br /&gt;Mount the iso image as the cdrom under qemu by using the "-cdrom &lt;path-to-iso&gt;" argument.&lt;br /&gt;&lt;br /&gt;Run Service Pack 2 from the virtual CD drive. I got an error message about an "Invalid Access to Memory Location" at one point during the install but it seemed to continue without a problem.&lt;br /&gt;References&lt;br /&gt;&lt;br /&gt;    * Running Microsoft Windows inside Debian: qemu&lt;br /&gt;    * QEMU - Debian - Linux - TUN/TAP - Network Bridge&lt;br /&gt;    * SP2 Reference&lt;br /&gt;&lt;br /&gt;Other Virtual Machines&lt;br /&gt;VMware&lt;br /&gt;Plex86&lt;br /&gt;Bochs&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-5520452739777556792?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/5520452739777556792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=5520452739777556792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5520452739777556792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5520452739777556792'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/qemu.html' title='qemu'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-5041824193525937235</id><published>2010-09-03T20:48:00.001+08:00</published><updated>2010-09-03T20:48:04.143+08:00</updated><title type='text'>googlecl examplescripts</title><content type='html'>   ExampleScripts   &lt;br /&gt;Example commands and tasks GoogleCL can do.&lt;br /&gt;&lt;br /&gt;Also see the Manual and the SystemRequirements. Note that (only) the first time you use each service, you'll need to grant authorization from a web browser.&lt;br /&gt;Blogger¶&lt;br /&gt;&lt;br /&gt;    * google blogger post --tags "GoogleCL, awesome" --title "Test Post" "I'm posting from the command line"&lt;br /&gt;    * google blogger post blogpost.txt&lt;br /&gt;    * google blogger list title,url-site # List posts&lt;br /&gt;    * google blogger delete --title "Test Post"&lt;br /&gt;    * google delete --title "Silly post number [0-9]*" # Delete posts matching regex&lt;br /&gt;    * google tag --title "Dev post" --tags "Python, software" # label an existing post &lt;br /&gt;&lt;br /&gt;Calendar¶&lt;br /&gt;&lt;br /&gt;    * google calendar add "Dinner party with George today at 6pm" # add event to calendar&lt;br /&gt;    * google calendar today # List events for today only.&lt;br /&gt;    * google calendar list --date 2010-06-01,2010-06-30 # List events.&lt;br /&gt;    * google calendar delete --title "Dinner party with George" # Delete an event.&lt;br /&gt;    * google calendar today list --cal .* | egrep '\[.*\]' # List all calendars &lt;br /&gt;&lt;br /&gt;Contacts¶&lt;br /&gt;&lt;br /&gt;    * google contacts add "J. Random Hacker, jrandom@example.com"&lt;br /&gt;    * google contacts list name,email --title "J. Random Hacker"&lt;br /&gt;    * google contacts delete --title "J. Random Hacker" &lt;br /&gt;&lt;br /&gt;Docs¶&lt;br /&gt;&lt;br /&gt;    * google docs delete --title "Evidence"&lt;br /&gt;    * google docs list title,url-direct --delimiter ": " # list docs&lt;br /&gt;    * google docs upload the_bobs.csv ~/work/docs_to_share/* &lt;br /&gt;&lt;br /&gt;gdata-python-client &gt;= 1.3.0 ONLY&lt;br /&gt;&lt;br /&gt;    * google docs edit --title "Shopping list" --editor vim&lt;br /&gt;    * google docs get --title "Homework [0-9]*" &lt;br /&gt;&lt;br /&gt;Picasa¶&lt;br /&gt;&lt;br /&gt;    * google picasa create --title "Vermont Test" --tags Vermont vermont.jpg&lt;br /&gt;    * google picasa get --title "Vermont Test" /path/to/download/folder&lt;br /&gt;    * google picasa list title,url-direct --query "A tag"&lt;br /&gt;    * google picasa post --title "Vermont Test" ~/old_photos/*.jpg # Add to an album&lt;br /&gt;    * google picasa tag --title "Vermont Test" --tags "places"&lt;br /&gt;    * google picasa delete --title "Vermont Test" # delete entire album &lt;br /&gt;&lt;br /&gt;Youtube¶&lt;br /&gt;&lt;br /&gt;    * google youtube post --category Education --devtags GoogleCL killer_robots.avi&lt;br /&gt;    * google youtube delete --title "killer_robots.avi"&lt;br /&gt;    * google youtube list # list my videos&lt;br /&gt;    * google youtube tag -n ".*robot.*" --tags robot &lt;br /&gt;&lt;br /&gt;Search, Buzz, Gmail, etc.¶&lt;br /&gt;&lt;br /&gt;We'd love to support more Google services with GoogleCL, but we're currently limited by the availability of gdata APIs.&lt;br /&gt;&lt;br /&gt;Before hacking in our own services, it's probably best if we encourage the gdata teams to add new services (and python interfaces to those new APIs) first. &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-5041824193525937235?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/5041824193525937235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=5041824193525937235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5041824193525937235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5041824193525937235'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/googlecl-examplescripts.html' title='googlecl examplescripts'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-19499458570120833</id><published>2010-09-03T20:41:00.001+08:00</published><updated>2010-09-03T20:41:40.534+08:00</updated><title type='text'>vim</title><content type='html'>高效率的使用VIM&lt;br /&gt;&lt;br /&gt;虽然从很久前就开始用 VIM 了，但一直都是半调吊子，翻来覆去只用自己会的命令。最近为了提高书写代码的效率，还有 coding 时候的乐趣，又重新钻研了一下 VIM，发现了一篇很好的 VIM 入门的文章，原文是英文版的，我觉得非常适合 VIM 使用入门，所以翻译了过来。这里是简单的介绍了 VIM 的操作方式，并没有说为什么要用 VIM，如果你想知道答案可以去 Google，VIM 被誉为编辑器之神。&lt;br /&gt;&lt;br /&gt;这篇教程写了在不同工作模式下使用 VIM 的一些基本技巧——即插入模式（insert mode）， 命令模式（command mode）， 存取文件等。目的是帮助刚刚接触 VIM 的新手更加有效率的使用这个出色的编辑器。&lt;br /&gt;&lt;br /&gt;说明：在这篇文章里面，&lt;C-X&gt; 代表 Ctrl + X——就是按住 Ctrl 键然后再按 X。而且你可以在很多情况下使用 :help command 来获得大部分命令的帮助，这个是 VIM 的内部帮助文件命令。&lt;br /&gt;&lt;br /&gt;高效率移动&lt;br /&gt;&lt;br /&gt;在插入模式之外&lt;br /&gt;&lt;br /&gt;基本上来说，你应该尽可能少的呆在插入模式里面，因为在插入模式里面 VIM 就像一个“哑巴”编辑器一样。很多新手都会一直呆在插入模式里面，因为这样易于使用。但 VIM 的强大之处在于他的命令行模式！你会发现，在你越来越了解 VIM 之后，你就会花越来越少的时间使用插入模式了。&lt;br /&gt;&lt;br /&gt;使用 h、j、k、l&lt;br /&gt;&lt;br /&gt;使用 VIM 高效率编辑的第一步，就是放弃使用箭头键。使用 VIM，你就不用频繁的在箭头键和字母键之间移来移去了，这会节省你很多时间。当你在命令模式时，你可以用 h、j、k、l 来分别实现左、下、上、右箭头的功能。一开始可能需要适应一下，但一旦习惯这种方式，你就会发现这样操作的高效之处了。&lt;br /&gt;&lt;br /&gt;在你编辑你的电子邮件或者其他有段落的文本时，你可能会发现使用方向键和你预期的效果不一样，有时候可能会一次跳过了很多行。这是因为你的段落在 VIM 看来是一个大的长长的行。这时你可以在按 h、j、k 或者 l 之前键入一个 g，这样 VIM 就会按屏幕上面的行如你所愿的移动了。&lt;br /&gt;&lt;br /&gt;在当前行里面有效的移动光标&lt;br /&gt;&lt;br /&gt;很多编辑器只提供了简单的命令来控制光标的移动（比如左、上、右、下、到行首/尾等）。VIM 则提供了很多强大的命令来满足你控制光标的欲望。当光标从一点移动到另外一点，在这两点之间的文本（包括这两个点）称作被“跨过”，这里的命令也被称作是 motion。（简单说明一下，后面会用到这个重要的概念）&lt;br /&gt;&lt;br /&gt;这里是常用到的一些命令（motion）：&lt;br /&gt;&lt;br /&gt;    * fx：移动光标到当前行的下一个 x 处。很明显，x 可以是任意一个字母，而且你可以使用 ; 来重复你的上一个 f 命令。&lt;br /&gt;    * tx：和上面的命令类似，但是是移动到 x 的左边一个位置。（这真的很有用）&lt;br /&gt;    * Fx：和 fx 类似，不过是往回找。&lt;br /&gt;    * w：光标往前移动一个词。&lt;br /&gt;    * b：光标往后移动一个词。&lt;br /&gt;    * 0：移动光标到当前行首。&lt;br /&gt;    * ^：移动光标到当前行的第一个字母位置。&lt;br /&gt;    * $：移动光标到行尾。&lt;br /&gt;    * )：移动光标到下一个句子。&lt;br /&gt;    * ( ：移动光标到上一个句子。&lt;br /&gt;&lt;br /&gt;在整个文件里面有效移动光标&lt;br /&gt;&lt;br /&gt;VIM 有很多命令，可以用来到达文件里面你想到达的地方。下面是一些在文件里面移动的命令：&lt;br /&gt;&lt;br /&gt;    * &lt;C-F&gt;：向下移动一屏。&lt;br /&gt;    * &lt;C-B&gt;：向上移动一屏。&lt;br /&gt;    * G：到文件尾&lt;br /&gt;    * numG：移动光标到指定的行（num）。（比如 10G 就是到第 10 行）&lt;br /&gt;    * gg：到文件首&lt;br /&gt;    * H：移动光标到屏幕上面&lt;br /&gt;    * M：移动光标到屏幕中间&lt;br /&gt;    * L：移动光标到屏幕下面&lt;br /&gt;    * *：读取光标处的字符串，并且移动光标到它再次出现的地方。&lt;br /&gt;    * #：和上面的类似，但是是往反方向寻找。&lt;br /&gt;    * /text：从当前光标处开始搜索字符串 text，并且到达 text 出现的地方。必须使用回车来开始这个搜索命令。如果想重复上次的搜索的话，按 n。&lt;br /&gt;    * ？text：和上面类似，但是是反方向。&lt;br /&gt;    * ma：在当前光标的位置标记一个书签，名字为 a。书签名只能是小写字母。你看不见书签的存在，但它确实已经在那里了。&lt;br /&gt;    * `a：到书签 a 处。注意这个不是单引号，它一般位于大部分键盘的 1 的左边。&lt;br /&gt;    * `.：到你上次编辑文件的地方。这个命令很有用，而且你不用自己去标记它。&lt;br /&gt;&lt;br /&gt;高效的输入&lt;br /&gt;&lt;br /&gt;使用关键词自动完成&lt;br /&gt;&lt;br /&gt;VIM 有一个非常漂亮的关键词自动完成系统。这表示，你可以输入一个长词的一部分，然后按一下某个键，然后 VIM 就替你完成了这个长词的输入了。举个例子：你有一个变量名为 iAmALongAndAwkwardVarName 在你写的代码的某个地方。也许你不想每回都自己一个一个字母的去输入它。&lt;br /&gt;&lt;br /&gt;使用关键词自动完成功能，你只需要输入开始几个字母（比如 iAmAL），然后按 &lt;C-N&gt;（按住 Ctrl，再按 N）或者 &lt;C-P&gt;。如果 VIM 没有给出你想要的词，继续按，直到你满意为止，VIM 会一直循环它找到的匹配的字符串。&lt;br /&gt;&lt;br /&gt;聪明的进入插入模式&lt;br /&gt;&lt;br /&gt;很多新手进入插入模式都只是用 i。这样当然可以进入插入模式，但通常不是那么合适，因为 VIM 提供了很多进入插入模式的命令。下面是最常用的一些：&lt;br /&gt;&lt;br /&gt;    * i：在当前字符的左边插入&lt;br /&gt;    * I：在当前行首插入&lt;br /&gt;    * a：在当前字符的右边插入&lt;br /&gt;    * A：在当前行尾插入&lt;br /&gt;    * o：在当前行下面插入一个新行&lt;br /&gt;    * O：在当前行上面插入一个新行&lt;br /&gt;    * c{motion}：删除 motion 命令跨过的字符，并且进入插入模式。比如：c$，这将会删除从光标位置到行尾的字符并且进入插入模式。ct！，这会删除从光标位置到下一个叹号（但不包括），然后进入插入模式。被删除的字符被存在了剪贴板里面，并且可以再粘贴出来。&lt;br /&gt;    * d{motion}：和上面差不多，但是不进入插入模式。&lt;br /&gt;&lt;br /&gt;有效的移动大段的文本&lt;br /&gt;&lt;br /&gt;使用可视选择（visual selections）和合适的选择模式&lt;br /&gt;&lt;br /&gt;不像最初的 VI，VIM 允许你高亮（选择）一些文本，并且进行操作。这里有三种可视选择模式：&lt;br /&gt;&lt;br /&gt;    * v：按字符选择。经常使用的模式，所以亲自尝试一下它。&lt;br /&gt;    * V：按行选择。这在你想拷贝或者移动很多行的文本的时候特别有用。&lt;br /&gt;    * &lt;C-V&gt;：按块选择。非常强大，只在很少的编辑器中才有这样的功能。你可以选择一个矩形块，并且在这个矩形里面的文本会被高亮。&lt;br /&gt;&lt;br /&gt;在选择模式的时候使用上面所述的方向键和命令（motion）。比如，vwww，会高亮光标前面的三个词。Vjj 将会高亮当前行以及下面两行。&lt;br /&gt;&lt;br /&gt;在可视选择模式下剪切和拷贝&lt;br /&gt;&lt;br /&gt;一旦你高亮了选区，你或许想进行一些操作：&lt;br /&gt;&lt;br /&gt;    * d：剪贴选择的内容到剪贴板。&lt;br /&gt;    * y：拷贝选择的内容到剪贴板。&lt;br /&gt;    * c：剪贴选择的内容到剪贴板并且进入插入模式。&lt;br /&gt;&lt;br /&gt;在非可视选择模式下剪切和拷贝&lt;br /&gt;&lt;br /&gt;如果你很清楚的知道你想拷贝或者剪切什么，那你根本就不需要进入可视选择模式。这样也会节省时间：&lt;br /&gt;&lt;br /&gt;    * d{motion}：剪切 motion 命令跨过的字符到剪贴板。比如，dw 会剪切一个词而 dfS 会将从当前光标到下一个 S 之间的字符剪切至剪贴板。&lt;br /&gt;    * y{motion}：和上面类似，不过是拷贝。&lt;br /&gt;    * c{motion}：和 d{motion} 类似，不过最后进入插入模式。&lt;br /&gt;    * dd：剪切当前行。&lt;br /&gt;    * yy：拷贝当前行。&lt;br /&gt;    * cc：剪切当前行并且进入插入模式。&lt;br /&gt;    * D：剪切从光标位置到行尾到剪贴板。&lt;br /&gt;    * Y：拷贝当前行。&lt;br /&gt;    * C：和 D 类似，最后进入插入模式。&lt;br /&gt;    * x：剪切当前字符到剪贴板。&lt;br /&gt;    * s：和x类似，不过最后进入插入模式。&lt;br /&gt;&lt;br /&gt;粘贴&lt;br /&gt;&lt;br /&gt;粘贴很简单，按 p。&lt;br /&gt;&lt;br /&gt;使用多重剪贴板&lt;br /&gt;&lt;br /&gt;很多编辑器都只提供了一个剪贴板。VIM 有很多。剪贴板在 VIM 里面被称为寄存器（Registers）。你可以列出当前定义的所有寄存器名和它们的内容，命令为“:reg”。最好使用小写字母来作为寄存器的名称，因为大写的有些被 VIM 占用了。&lt;br /&gt;&lt;br /&gt;使用寄存器的命令为双引号 “。&lt;br /&gt;&lt;br /&gt;比如：我们要拷贝当前行到寄存器 k。你应该按 “kyy。（你也可以使用 V”ky。为什么这样也可以呢？）现在当前行应该已经存在了寄存器 k 里面直到你又拷贝了一些东西进入寄存器 k。现在你可以使用命令 “kp 来粘贴寄存器 k 里面的内容到你想要的位置。&lt;br /&gt;&lt;br /&gt;避免重复&lt;br /&gt;&lt;br /&gt;令人惊奇的 . 命令&lt;br /&gt;&lt;br /&gt;在 VI 里面，输入 . (小数点符号），将会重复你输入的上一个命令。比如，你上个命令为“dw”（删除一个词），VI 将会接着再删除一个词。&lt;br /&gt;&lt;br /&gt;使用数字&lt;br /&gt;&lt;br /&gt;使用数字也是 VIM 强大的而且很节省时间的重要特性之一。在很多 VIM 的命令之前都可以使用一个数字，这个数字将会告诉 VIM 这个命令需要执行几次。比如：&lt;br /&gt;&lt;br /&gt;    * 3j 将会把光标向下移动三行。&lt;br /&gt;    * 10dd 将会删除十行。&lt;br /&gt;    * y3″ 将会拷贝从当前光标到第三个出现的引号之间的内容到剪贴板。&lt;br /&gt;&lt;br /&gt;数字是扩展 motion 命令作用域非常有效的方法。&lt;br /&gt;&lt;br /&gt;记录宏&lt;br /&gt;&lt;br /&gt;有时候，你会发现你自己在文章的每段或者每行都重复相同的一系列动作。VIM 允许你记录一个宏来完成你的特殊需要。&lt;br /&gt;&lt;br /&gt;    * qregister：记录宏到寄存器 register，这里 register 是任意的你的寄存器的名字。比如 qa，将会记录并且把宏存在寄存器 a 里面。&lt;br /&gt;    * q：结束宏的记录。&lt;br /&gt;    * @register：使用存在寄存器 register 的宏。比如 @a，将会使用存在寄存器 a 里面的宏。&lt;br /&gt;&lt;br /&gt;必须要记住的是，宏只记录了你的系列按键并且重复执行它们。它们不是魔法。因为在 VIM 里面完成目的的方法有很多，所以有时候你要小心选择命令来记录你的宏。因为它们会在所有你要执行它的地方执行。&lt;br /&gt;&lt;br /&gt;用 VIM 写代码&lt;br /&gt;&lt;br /&gt;VIM 是一个用来写代码的绝好编辑器，因为它有一些特性是专门为程序员而设计的。这里是一些常用的：&lt;br /&gt;&lt;br /&gt;    * ]p：和 p 的功能差不多，但是它会自动调整被粘贴的文本的缩进去适应当前代码的位置。试一下！&lt;br /&gt;    * %：匹配花括号、方括号、括号等。在一个括号的上面，然后按 %，鼠标就会出现在匹配的另外一半括号处。&lt;br /&gt;    * &gt;&gt;：缩进所有选择的代码&lt;br /&gt;    * &lt;&lt;：和上面类似，但是反缩进&lt;br /&gt;    * gd：到达光标所在处函数或者变量的定义处。&lt;br /&gt;    * K：在 Man 里面查找光标当前所在处的词&lt;br /&gt;&lt;br /&gt;移动光标&lt;br /&gt;上:k nk:向上移动n行 9999k或gg可以移到第一行 G移到最后一行&lt;br /&gt;下:j nj:向下移动n行&lt;br /&gt;左:h nh:向左移动n列&lt;br /&gt;右:l nl:向右移动n列&lt;br /&gt;&lt;br /&gt;w：光标以单词向前移动 nw：光标向前移动n个单词 光标到单词的第一个字母上&lt;br /&gt;b：与w相反&lt;br /&gt;e: 光标以单词向前移动 ne：光标向前移动n个单词 光标到单词的最后一个字母上&lt;br /&gt;ge:与e相反&lt;br /&gt;&lt;br /&gt;$:移动光标到行尾 n$:移动到第n行的行尾&lt;br /&gt;0（Num）：移动光标到行首&lt;br /&gt;^:移动光标到行首第一个非空字符上去&lt;br /&gt;&lt;br /&gt;f&lt;a&gt;:移动光标到当前行的字符a上，nf&lt;a&gt;移动光标到当前行的第n个a字符上&lt;br /&gt;F:相反&lt;br /&gt;&lt;br /&gt;%:移动到与制匹配的括号上去（），{}，[]，&lt;&gt;等。&lt;br /&gt;&lt;br /&gt;nG:移动到第n行上 G:到最后一行&lt;br /&gt;&lt;br /&gt;CTRL＋G 得到当前光标在文件中的位置&lt;br /&gt;&lt;br /&gt;向前翻页：CTRL+F&lt;br /&gt;向下移动半屏：CTRL＋G&lt;br /&gt;向后翻页：CTRL+B&lt;br /&gt;&lt;br /&gt;存盘：&lt;br /&gt;:q! :不存盘退出&lt;br /&gt;:e! :放弃修改文件内容，重新载入该文件编辑&lt;br /&gt;:wq ：存盘退出&lt;br /&gt;&lt;br /&gt;dw：删除一个单词,需将光标移到单词的第一个字母上，按dw，如果光标在单词任意位置，用daw&lt;br /&gt;dnw:删除n个单词&lt;br /&gt;dne:也可，只是删除到单词尾&lt;br /&gt;dnl:向右删除n个字母&lt;br /&gt;dnh:向左删除n个字母&lt;br /&gt;dnj:向下删除n行&lt;br /&gt;dnk:向上删除n行&lt;br /&gt;d$：删除当前光标到改行的行尾的字母&lt;br /&gt;dd：删除一行&lt;br /&gt;cnw[word]:将n个word改变为word&lt;br /&gt;cc:改变整行&lt;br /&gt;C$:改变到行尾&lt;br /&gt;&lt;br /&gt;J: 删除换行符，将光标移到改行，按shift+j删除行尾的换行符，下一行接上来了.&lt;br /&gt;u: 撤销前一次的操作&lt;br /&gt;shif+u(U):撤销对该行的所有操作。&lt;br /&gt;&lt;br /&gt;:set showmode :设置显示工作模式&lt;br /&gt;&lt;br /&gt;o：在当前行的下面另起一行&lt;br /&gt;O（shift+o)：在当前行的上面另起一行&lt;br /&gt;&lt;br /&gt;nk或nj：光标向上或向下移n行，n为数字&lt;br /&gt;an!【ESC】：在行后面加n个感叹号(!)&lt;br /&gt;nx:执行n次x(删除)操作&lt;br /&gt;&lt;br /&gt;ZZ：保存当前文档并退出VIM&lt;br /&gt;&lt;br /&gt;:help ：查看帮助文档，在这之中，按CTRL+] 进入超连接，按CTRL＋O 返回。&lt;br /&gt;:help subject :看某一主题的帮助，ZZ 退出帮助&lt;br /&gt;&lt;br /&gt;:set number / set nonumber :显示/不显示行号&lt;br /&gt;:set ruler /set noruler:显示/不显示标尺&lt;br /&gt;&lt;br /&gt;/pattern 正方向搜索一个字符模式&lt;br /&gt;?pattern 反方向搜索一个字符模式&lt;br /&gt;然后按n 继续向下找&lt;br /&gt;&lt;br /&gt;把光标放到某个单词上面，然后按×号键，表示查找这个单词&lt;br /&gt;查找整个单词：/\&lt;word\&gt;&lt;br /&gt;&lt;br /&gt;:set hlsearch 高亮显示查找到的单词&lt;br /&gt;:set nohlsearch 关闭改功能&lt;br /&gt;&lt;br /&gt;m[a-z]:在文中做标记，标记号可为a-z的26个字母，用`a可以移动到标记a处&lt;br /&gt;&lt;br /&gt;r:替换当前字符&lt;br /&gt;nr字符：替换当前n个字符&lt;br /&gt;&lt;br /&gt;查找替换：&lt;br /&gt;way1:&lt;br /&gt;/【word】 :查找某个word&lt;br /&gt;cw【newword】:替换为新word&lt;br /&gt;n: 继续查找&lt;br /&gt;.: 执行替换&lt;br /&gt;&lt;br /&gt;way2:&lt;br /&gt;:s/string1/string2/g:在一行中将string1替换为string2,g表示执行 用c表示需要确认&lt;br /&gt;:num1,num2 s/string1/string2/g:在行num1至num2中间将string1替换为string2&lt;br /&gt;:1,$ s/string1/string2/g:在全文中将string1替换为string2&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;v:进入visual 模式&lt;br /&gt;【ESC】退出&lt;br /&gt;V:shift+v 进入行的visual 模式&lt;br /&gt;CTRL+V:进如块操作模式用o和O改变选择的边的大小。&lt;br /&gt;&lt;br /&gt;粘贴：p，这是粘贴用x或d删除的文本&lt;br /&gt;复制：&lt;br /&gt;ynw：复制n个单词&lt;br /&gt;yy：复制一行&lt;br /&gt;ynl:复制n个字符&lt;br /&gt;y$:复制当前光标至行尾处&lt;br /&gt;nyy:拷贝n行&lt;br /&gt;完了用p粘贴&lt;br /&gt;&lt;br /&gt;:split:分割一个窗口&lt;br /&gt;:split file.c ：为另一个文件file.c分隔窗口&lt;br /&gt;:nsplit file.c: 为另一个文件file.c分隔窗口，并指定其行数&lt;br /&gt;CTRL＋W在窗口中切换&lt;br /&gt;:close：关闭当前窗口&lt;br /&gt;&lt;br /&gt;在所有行插入相同的内容如include&lt;，操作方法如下：&lt;br /&gt;将光标移到开始插入的位置，按CTRL+V进入VISUAL模式，选择好模块后&lt;br /&gt;按I（shift+i)，后插入要插入的文本，按[ESC]完成。&lt;br /&gt;&lt;br /&gt;:read file.c 将文件file.c的内容插入到当前光标所在的下面&lt;br /&gt;:0read file.c 将文件file.c的内容插入到当前文件的开始处(第0行）&lt;br /&gt;:nread file.c 将文件file.c的内容插入到当前文件的第n行后面&lt;br /&gt;:read !cmd :将外部命令cmd的输出插如到当前光标所在的下面&lt;br /&gt;&lt;br /&gt;:n1,n2 write temp.c 将本文件中的n1,到n2行写入temp.c这个文件中去&lt;br /&gt;&lt;br /&gt;CTRL＋L刷新屏幕&lt;br /&gt;shift + &lt; 左移一行&lt;br /&gt;shift + &gt; 右移一行&lt;br /&gt;&lt;br /&gt;u: undo&lt;br /&gt;CTRL+R: re-do&lt;br /&gt;J: 合并一行&lt;br /&gt;CTRL+p 自动完成功能&lt;br /&gt;CTRL+g 查看当前文件全路径&lt;br /&gt;&lt;br /&gt;q[a-z] 开始记录但前开始的操作为宏，名称可为【a-z】，然后用q终止录制宏。&lt;br /&gt;用reg显示当前定义的所有的宏，用@[a-z]来在当前光标处执行宏[a-z].&lt;br /&gt;&lt;br /&gt;Copyright by abnerchai, 2005.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-19499458570120833?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/19499458570120833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=19499458570120833' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/19499458570120833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/19499458570120833'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2010/09/vim.html' title='vim'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-1930236786809505713</id><published>2008-12-09T15:26:00.000+08:00</published><updated>2008-12-09T15:28:48.526+08:00</updated><title type='text'>option, options, optionsCollection</title><content type='html'>http://zhidao.baidu.com/question/13087595.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-1930236786809505713?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/1930236786809505713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=1930236786809505713' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1930236786809505713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1930236786809505713'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2008/12/option-options-optionscollection.html' title='option, options, optionsCollection'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-8809628612030605467</id><published>2008-12-08T14:27:00.000+08:00</published><updated>2008-12-08T14:28:43.463+08:00</updated><title type='text'>jsp通过logic:iterate或html:optionsCollection循环显示action中传过来的对象List</title><content type='html'>http://www.blogjava.net/ec2008/archive/2007/09/15/145440.html&lt;br /&gt;&lt;br /&gt;action中代码如下：&lt;br /&gt;&lt;div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"&gt;&lt;!--&lt;br /&gt; &lt;br /&gt; Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt; http://www.CodeHighlighter.com/&lt;br /&gt; &lt;br /&gt; --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        List allUser&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.getLoginServiceImpl().find();&lt;br /&gt;        request.setAttribute(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, allUser);&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; mapping.findForward(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;listUser&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);&lt;/span&gt;&lt;/div&gt; 注：其中User对象有id和name属性&lt;br /&gt;&lt;br /&gt;jsp显示：法一&lt;br /&gt;&lt;div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"&gt;&lt;!--&lt;br /&gt; &lt;br /&gt; Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt; http://www.CodeHighlighter.com/&lt;br /&gt; &lt;br /&gt; --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select property&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;school&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:option value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;bean:message key&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;login.select&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:option&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;logic:present name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;logic:iterate id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; offset&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;option value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;bean:write name="&lt;/span"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; property=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;bean:write name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; property&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;option&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;logic:iterate&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;logic:present&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;/div&gt; jsp显示：法二&lt;br /&gt;&lt;div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"&gt;&lt;!--&lt;br /&gt; &lt;br /&gt; Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt; http://www.CodeHighlighter.com/&lt;br /&gt; &lt;br /&gt; --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;       &lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select property&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;school&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:optionsCollection name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; label&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;       &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;optionsCollection标签用法：&lt;br /&gt;与options标签一样，optionsCollection标签可以从集合或者是包含集合的对象里获得选项的标签/值对。在这两种情况里，集合或包含集合的对象必须是一个作用域对象，否则定制标签将无法访问它。&lt;br /&gt;&lt;br /&gt;1.与包含集合的对象配合使用&lt;br /&gt;举例：userForm动作表单有一个如下所示的ArrayList类型的userList属性，相应的set，get方法，通过在action中设置好userForm后，request.setAttribute("userForm",userForm)；&lt;br /&gt;在jsp页面：&lt;br /&gt;&lt;div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"&gt;&lt;!--&lt;br /&gt; &lt;br /&gt; Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt; http://www.CodeHighlighter.com/&lt;br /&gt; &lt;br /&gt; --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select property&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;school&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:optionsCollection name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;userForm&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;      property&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;userList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;2.与集合配合使用&lt;br /&gt;action中&lt;br /&gt;&lt;div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"&gt;&lt;!--&lt;br /&gt; &lt;br /&gt; Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt; http://www.CodeHighlighter.com/&lt;br /&gt; &lt;br /&gt; --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ArrayList userList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ArrayList();&lt;br /&gt;userList.add(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; LabelValueBean(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;haha&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;));&lt;br /&gt;userList.add(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; LabelValueBean(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;dada&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;));&lt;br /&gt;userList.add(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; LabelValueBean(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;xiaoxiao&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;));&lt;br /&gt;request.setAttribute(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;userList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,userList);&lt;/span&gt;&lt;/div&gt; jsp页面&lt;br /&gt;&lt;div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"&gt;&lt;!--&lt;br /&gt; &lt;br /&gt; Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt; http://www.CodeHighlighter.com/&lt;br /&gt; &lt;br /&gt; --&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select property&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;school&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:optionsCollection name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;userList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;      label&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;label&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;/&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;html:select&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-8809628612030605467?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/8809628612030605467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=8809628612030605467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8809628612030605467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8809628612030605467'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2008/12/jsplogiciteratehtmloptionscollectionact.html' title='jsp通过logic:iterate或html:optionsCollection循环显示action中传过来的对象List'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-3750023848310673430</id><published>2008-11-27T17:10:00.000+08:00</published><updated>2008-11-27T17:11:18.738+08:00</updated><title type='text'>实战：Ubuntu Dapper下架设Tomcat5+MySQL5+JSP</title><content type='html'>http://forum.ubuntu.org.cn/viewtopic.php?f=43&amp;amp;t=24111&lt;br /&gt;&lt;br /&gt;最近正在制作一个jsp的Web应用项目，项目组内一共是四个成员，其它成员都是在Windows下工作，只有我在Linux下工作。我的工作就是进行后 期的页面布局和服务器的架设，以及编码的统一（GB2312-&gt;UTF-8）。一周前在Windows下tomcat+mysql测试好的几份后台 代码交到了我这里，本来没有在意服务器的架设，以为很简单，没想到怎么安装都是出错。前前后后用了一周多的时间，昨天夜里总算把服务器架起来了。在这里分 享一下经验。&lt;br /&gt;&lt;br /&gt;首先确认已经安照新手设置指南里的方法安装好了jdk，然后在系统中填加JAVA环境变量&lt;br /&gt;sudo gedit /etc/bash.bashrc&lt;br /&gt;在结尾处增加&lt;br /&gt;export JAVA_HOME=/usr/jvm/java-1.5.0-sun&lt;br /&gt;export JRE=$JAVA_HOME/jre&lt;br /&gt;&lt;br /&gt;一、Tomcat&lt;br /&gt;1、安装&lt;br /&gt;sudo aptitude install tomcat5 tomcat5-admin tomcat5-webapps&lt;br /&gt;2、设置&lt;br /&gt;Tomcat默认的admin和manager帐号是没有启用的，可以编辑/usr/share/tomcat5/conf/tomcat-users.xml文件来启用&lt;br /&gt;&lt;br /&gt;cd /usr/share/tomcat5/conf&lt;br /&gt;sudo gedit tomcat-users.xml&lt;br /&gt;&lt;br /&gt;在里面新增两个角色admin和manager，增加一个用户root，密码为123456(这里只是例子，用户名和密码可以自己设)，编辑后的文件为：&lt;br /&gt;&lt;div class="quotetitle"&gt;&lt;b&gt;引用:&lt;/b&gt;&lt;/div&gt;&lt;div class="quotecontent"&gt;&lt;br /&gt;&lt;tomcat-users&gt;&lt;br /&gt;&lt;role rolename="tomcat"&gt;&lt;br /&gt;&lt;role rolename="role1"&gt;&lt;br /&gt;&lt;role rolename="admin"&gt;&lt;br /&gt;&lt;role rolename="manager"&gt;&lt;br /&gt;&lt;user username="root" password="123456" roles="admin,manager"&gt;&lt;br /&gt;&lt;user username="tomcat" password="tomcat" roles="tomcat"&gt;&lt;br /&gt;&lt;user username="both" password="tomcat" roles="tomcat,role1"&gt;&lt;br /&gt;&lt;user username="role1" password="tomcat" roles="role1"&gt;&lt;br /&gt;&lt;/user&gt;&lt;br /&gt;&lt;/user&gt;&lt;/user&gt;&lt;/user&gt;&lt;/role&gt;&lt;/role&gt;&lt;/role&gt;&lt;/role&gt;&lt;/tomcat-users&gt;&lt;/div&gt;&lt;br /&gt;保存退出,重启tomcat&lt;br /&gt;sudo /etc/init.d/tomcat5 restart&lt;br /&gt;3、测试&lt;br /&gt;这时在浏览器里打开http://127.0.0.1:8180，看见页面就说明Tomcat已经安装成功了。然后可以点击左侧的Tomcat Administration和Tomcat Manager进行管理员和站点管理页面。运行首页里左侧的Examples里面的实例可以测试一下jsp运行情况。&lt;br /&gt;其实我个人觉得添加这个管理用户没有多大必要，由于权限，在管理页面进行的更改重启后又会消失。因此如果一定要在管理页面进行更改，请设定Tomcat目 录的权限为所有用户可写。即sudo chmod 777 -R /usr/share/tomcat5。个人不推荐这和作法，因为这样会破坏安全性。推荐使用文本进行配置，会在后面谈到。&lt;br /&gt;&lt;br /&gt;二、MySQL&lt;br /&gt;1、安装&lt;br /&gt;sudo aptitude install mysql mysql-admin mysql-client-5.0 mysql-navigator mysql-query-browser mysql-server-5.0&lt;br /&gt;2、测试并建立测试帐号&lt;br /&gt;安装后进入终端输入&lt;br /&gt;sudo mysql -uroot&lt;br /&gt;新建一个测试帐号javatest，密码为javadude,并指定可从任意主机登录，授权这个用户拥有数据库javatest的所有权限。添加一个数据库javatest&lt;br /&gt;&lt;div class="quotetitle"&gt;&lt;b&gt;引用:&lt;/b&gt;&lt;/div&gt;&lt;div class="quotecontent"&gt;mysql&gt;GRANT ALL PRIVILEGES ON javatest.* TO javauser@"%" IDENTIFIED BY "javadude";&lt;br /&gt;mysql&gt;create database javatest;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;三、安装JDBC驱动&lt;br /&gt;到http://dev.mysql.com/downloads/connector/j/5.0.html 下载驱动，仅仅解压其中的mysql-connector-java-5.0.3-bin.jar的文件，复制到/usr/share/tomcat5 /common/lib下即可。&lt;br /&gt;教育网速度慢的话可以到http://mysql.mirror.edu.cn下载。&lt;br /&gt;四、测试Tomcat+MySQL&lt;br /&gt;添加一个虚拟目录&lt;br /&gt;cd /usr/share/tomcat5/conf/Catalina/localhost&lt;br /&gt;sudo gedit javatest.xml&lt;br /&gt;添加如下信息：&lt;br /&gt;&lt;div class="quotetitle"&gt;&lt;b&gt;引用:&lt;/b&gt;&lt;/div&gt;&lt;div class="quotecontent"&gt;&lt;context path="/javatest" docbase="javatest" debug="0" reloadable="true"&gt;&lt;br /&gt;&lt;/context&gt;&lt;/div&gt;&lt;br /&gt;然后进入tomcat5的webapps目录，添加一个javatest目录，并在其中添加一个文件test.jsp&lt;br /&gt;cd /usr/share/tomcat5/webapps&lt;br /&gt;sudo mkdir javatest&lt;br /&gt;sudo gedit test.jsp&lt;br /&gt;编辑里面的内容为&lt;br /&gt;&lt;div class="quotetitle"&gt;&lt;b&gt;引用:&lt;/b&gt;&lt;/div&gt;&lt;div class="quotecontent"&gt;&lt;%@ page contentType="text/html; charset=utf-8" %&gt;&lt;br /&gt;&lt;%@ page language="java" %&gt;&lt;br /&gt;&lt;%@ page import="com.mysql.jdbc.Driver" %&gt;&lt;br /&gt;&lt;%@ page import="java.sql.*" %&gt;&lt;br /&gt;&lt;%  Class.forName("com.mysql.jdbc.Driver").newInstance();  Connection conn=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/javatest?user=javauser&amp;amp;password=javadude");  Statement stmt=conn.createStatement(); %&gt; &lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;建议使用这种方法进行测试，当然还有两种方法可以添加虚拟目录，一个是编辑conf下的server.xml把先前javatest.xml中的 内容填加server.xml中最末页的前面。另一种方法是不必创建javatest目录，而是将test.jsp打包建立归 档文件，并选择war类型，放到webapps下面，Tomcat会自动安装名为javatest的虚拟目录。&lt;br /&gt;&lt;br /&gt;注：到目前为止可能会出现几个问题，一会儿会谈到。&lt;br /&gt;&lt;br /&gt;接下来重启Tomcat&lt;br /&gt;sudo /etc/init.d/tomcat5 restart&lt;br /&gt;通常情况的话，这时便已经可以了。打开浏览器，输入http://127.0.0.1:8180，然后进入Tomcat Manager，可以看到一个名为javatest的目录，点击后会看到一个文件列表，点击其中的test.jsp。如果看到一个空白页面，说明正常。这 时可以从终端登录mysql，通过命令show processlist;查看当前连接到的用户信息。&lt;br /&gt;&lt;br /&gt;什么？打开test.jsp时只看到一片错误信息？别急，我说了，这里可能会遇到几个问题，如果是通常情况下上面的配置是正确的，就可以看到空白 页面和MySQL下的连接信息了。不过目前Ubuntu自带的MySQL和Tomcat存在两个问题（我不知道算不算是BUG），因此连不上很正常。&lt;br /&gt;&lt;br /&gt;*问题一：有可能MySQL没有使用locahost:3306，即127.0.0.1:3306，而是使用的本机IP或其它地址作为连接地址。 可以通过telnet 127.0.0.1 3306来测试一下，如果是拒绝连接，就是存在这个问题了，这个和打开test.jsp里面的access denied很像。&lt;br /&gt;*问题二：通过/etc/init.d/tomcat启动tomcat服务时跟本无法连接数据库，而要通过/usr/share/tomcat/bin/startup.sh来启动。&lt;br /&gt;&lt;br /&gt;找到这个原因非常困难，一直以为问题出在jdbc驱动上，随即下载添加mysql-connnect，调试，用了一周多的时间，也没有解决问题。&lt;br /&gt;好了，现在可以解决了。&lt;br /&gt;首先编辑MySQL的配置文件/etc/mysql/my.cnf，将其中bind-address的默认值由本机IP换成127.0.0.1。&lt;br /&gt;然后停止tomcat&lt;br /&gt;sudo /etc/init.d/tomcat stop&lt;br /&gt;再通过startup.sh启动tomcat&lt;br /&gt;sudo /usr/share/tomcat5/bin/startup.sh&lt;br /&gt;OK,这时打开浏览器，输入http://127.0.0.1:8180/javatest/test.jsp，按下回车，界面空白。终端下登录mysql，使用show processlist;查看，可以看到一个User为javauser的用户已经登录。&lt;br /&gt;不过开机会自动运行/etc/init.d下的tomcat5，我一直想找到这个文件的问题所在并进行修正，不过我对shell编程不是很了解。 目前的解决方法，只能是开机时禁止这个文件的运行，并使用usr/share/tomcat5/bin下的startup.sh启动服务器。&lt;br /&gt;&lt;br /&gt;至此，大功告成！&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-3750023848310673430?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/3750023848310673430/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=3750023848310673430' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3750023848310673430'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3750023848310673430'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2008/11/ubuntu-dappertomcat5mysql5jsp.html' title='实战：Ubuntu Dapper下架设Tomcat5+MySQL5+JSP'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-6207904959814550775</id><published>2008-11-27T15:24:00.000+08:00</published><updated>2008-11-27T16:16:08.602+08:00</updated><title type='text'>在Ubuntu Linux下安装Tomcat</title><content type='html'>http://unix-cd.com/vc/www/22/2008-07/10220.html&lt;br /&gt;&lt;br /&gt;对Linux还不是非常熟悉，昨天摸索了一下午，发现在Ubuntu下安装Tomcat并不是很困难，几乎只用apt-get就可以搞定。写在这里记录一下。&lt;br /&gt;&lt;br /&gt;首先要确定软件源的设置，打开“System”－“Administration”－“Software Sources”，把它调整成下面这个样子：&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;把那几项全部选中是个好习惯，省得在apt-get install过程中出现“无法找到软件包”的错误。&lt;br /&gt;&lt;br /&gt;接着安装Java环境，直接sudo apt-get install sun-java6-jre sun-java6-jdk就行了，安装完成后建议用&lt;br /&gt;&lt;br /&gt;sudo update-alternatives --config java&lt;br /&gt;sudo update-alternatives --config javac&lt;br /&gt;&lt;br /&gt;来设置一下默认的Java解释器和编译器，Linux下可能有多个Java环境，我认为还是选择SUN的比较保险。&lt;br /&gt;&lt;br /&gt;然后就是Tomcat了：&lt;br /&gt;&lt;br /&gt;sudo apt-get install tomcat5.5&lt;br /&gt;&lt;br /&gt;完成之后tomcat会自动启动。如果要手工启动/重启/停止Tomcat，建议使用sudo /etc/init.d/tomcat5.5 start | restart | stop，我发现这样并不用像很多网上说的那样需要设置JAVA_HOME之类的环境变量。&lt;br /&gt;&lt;br /&gt;Ubuntu下的Tomcat默认端口是8180，而不是Windows下通常的8080。Tomcat启动后，打开 http://localhost:8180/什么都不会看到，因为Ubuntu下的Tomcat并不带示例，当然如果你想安装示例应用，只要安装 tomcat5.5-webapps这个软件包就行了。&lt;br /&gt;&lt;br /&gt;打开/etc/tomcat5.5/server.xml，找到&lt;br /&gt;&lt;br /&gt;&lt;connector port="8180" maxhttpheadersize="8192"&gt;&lt;/connector&gt;maxThreads="150" minSpareThreads="25" maxSpareThreads="75"&lt;br /&gt;enableLookups="false" redirectPort="8443" acceptCount="100"&lt;br /&gt;connectionTimeout="20000" disableUploadTimeout="true" /&gt;&lt;br /&gt;&lt;br /&gt;这一堆，把port="8180"改成port="8080"，重启Tomcat，就会使用8080端口了，这样会习惯一些。&lt;br /&gt;&lt;br /&gt;最后还需要设定一下Web根目录。我为了平时的方便，把它指定到了我的用户目录下。在/etc/tomcat5.5/Catalina/localhost/下创建一个xml文件，比如说是ROOT.xml，在里面加上如下的内容：&lt;br /&gt;&lt;context pat="/" docbase="/home/albert/Programs/JavaEE" reloadable="true"&gt;&lt;/context&gt;&lt;br /&gt;重启Tomcat，在/home/albert/Programs/JavaEE中写一个test.jsp文件，打开http://localhost:8080/test.jsp测试一下，应该就没问题了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-6207904959814550775?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/6207904959814550775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=6207904959814550775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/6207904959814550775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/6207904959814550775'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2008/11/ubuntu-linuxtomcat.html' title='在Ubuntu Linux下安装Tomcat'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-3327231276050751609</id><published>2007-07-17T21:49:00.000+08:00</published><updated>2007-07-17T21:52:29.753+08:00</updated><title type='text'>smbclient share printer</title><content type='html'>keywords: smbclient printer howto&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.cn/search?complete=1&amp;hl=zh-CN&amp;amp;newwindow=1&amp;q=smbclient+printer+howto&amp;amp;meta"&gt;http://www.google.cn/search?complete=1&amp;hl=zh-CN&amp;amp;newwindow=1&amp;q=smbclient+printer+howto&amp;amp;meta&lt;/a&gt;=&lt;br /&gt;&lt;br /&gt;&lt;a href="http://man.chinaunix.net/linux/how/SMB-HOWTO-7.html"&gt;http://man.chinaunix.net/linux/how/SMB-HOWTO-7.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-3327231276050751609?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/3327231276050751609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=3327231276050751609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3327231276050751609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3327231276050751609'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/07/smbclient-share-printer.html' title='smbclient share printer'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-4211571570158153241</id><published>2007-03-06T19:21:00.000+08:00</published><updated>2007-03-06T19:23:29.305+08:00</updated><title type='text'>share virtual ip in hostonly setting in vmware standalone</title><content type='html'>&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-4211571570158153241?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/4211571570158153241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=4211571570158153241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4211571570158153241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4211571570158153241'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/03/share-virtual-ip-in-hostonly-setting-in.html' title='share virtual ip in hostonly setting in vmware standalone'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-5564880231211085201</id><published>2007-03-06T19:18:00.000+08:00</published><updated>2007-03-06T19:20:22.458+08:00</updated><title type='text'>vmware share connection via standalone host PC</title><content type='html'>the sample of vmware host setting&lt;br /&gt;&lt;a href="http://www.chinaunix.net/jh/4/374483.html"&gt;http://www.chinaunix.net/jh/4/374483.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-5564880231211085201?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/5564880231211085201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=5564880231211085201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5564880231211085201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5564880231211085201'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/03/vmware-share-connection-via-standalone.html' title='vmware share connection via standalone host PC'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-1951088872181067554</id><published>2007-02-25T20:53:00.000+08:00</published><updated>2007-02-25T20:54:58.791+08:00</updated><title type='text'>xmame's parameter</title><content type='html'>http://my.opera.com/kliz/blog/xmame&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;### File I/O-related ###&lt;br /&gt;rompath                 /media/hdb8/Emulation/mame100/roms #rom的位置&lt;br /&gt;samplepath              /media/hdb8/Emulation/mame100/samples #sample声音采样的位置&lt;br /&gt;inipath                 $HOME/.xmame/ini&lt;br /&gt;cfg_directory           $HOME/.xmame/cfg&lt;br /&gt;nvram_directory         $HOME/.xmame/nvram&lt;br /&gt;memcard_directory       $HOME/.xmame/memcard&lt;br /&gt;input_directory         $HOME/.xmame/inp&lt;br /&gt;hiscore_directory       $HOME/.xmame/hi&lt;br /&gt;state_directory         $HOME/.xmame/sta&lt;br /&gt;artwork_directory       /media/hdb8/Emulation/mame100/artwork&lt;br /&gt;snapshot_directory      /media/hdb8/Emulation/mame100/snap&lt;br /&gt;diff_directory          $HOME/.xmame/diff&lt;br /&gt;ctrlr_directory         /media/hdb8/Emulation/mame100/ctrlr&lt;br /&gt;cheat_file              /home/kliz/.xmame/cheat.dat&lt;br /&gt;hiscore_file            /media/hdb8/Emulation/mame100/hiscore.dat&lt;br /&gt;# record                &lt;null&gt; (not set)&lt;br /&gt;# playback              &lt;null&gt; (not set)&lt;br /&gt;log                     0&lt;br /&gt;### MAME Related ###&lt;br /&gt;defaultgame             dino #默认游戏，如果不指定游戏名称会使用这个&lt;br /&gt;language                english&lt;br /&gt;fuzzycmp                1 #模糊游戏名称匹配，会自动载入名字最相近的游戏&lt;br /&gt;cheat                   1 #开启作弊&lt;br /&gt;skip_gameinfo           1 #跳过游戏信息&lt;br /&gt;bios                    default #&lt;br /&gt;# state                 &lt;null&gt; (not set)&lt;br /&gt;autosave                0 #自动存档&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-1951088872181067554?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/1951088872181067554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=1951088872181067554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1951088872181067554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1951088872181067554'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/xmames-parameter.html' title='xmame&apos;s parameter'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-5165049806013983004</id><published>2007-02-24T05:06:00.000+08:00</published><updated>2007-02-24T05:15:20.785+08:00</updated><title type='text'>how to ignore case in vim</title><content type='html'>to make case insensitive matching in vim , just type :set ignorecase in vim command mode or set vimrc in home.&lt;br /&gt;the vim also have the very useful function, syntax on, which can highlight the syntax by default&lt;br /&gt;the compatible in vimrc is not recommended to check, for we only get the totally vi editing style after we confirm it. e.g. we will got A if we press up in editing mode; the u button only works at the first hit. That's not good at all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-5165049806013983004?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/5165049806013983004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=5165049806013983004' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5165049806013983004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5165049806013983004'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/how-to-ignore-case-in-vim.html' title='how to ignore case in vim'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-707960408364981938</id><published>2007-02-20T18:28:00.000+08:00</published><updated>2007-02-20T18:32:30.282+08:00</updated><title type='text'>cursor didn't show</title><content type='html'>after my shutting down my X, I restart X and found the curse doesn't shown anymore. and I found this to handle it:&lt;br /&gt;in the file /etc/X11/xorg.conf&lt;br /&gt;join in Section "Device"&lt;br /&gt;        Option       "HWCursor" "false"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-707960408364981938?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/707960408364981938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=707960408364981938' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/707960408364981938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/707960408364981938'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/cursor-didnt-show.html' title='cursor didn&apos;t show'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-5352649633674407983</id><published>2007-02-15T16:29:00.000+08:00</published><updated>2007-02-27T17:00:28.251+08:00</updated><title type='text'>bash script practice</title><content type='html'>while (( i&lt;100 a="1" b="2" style="display: block; padding-left: 6em; text-indent: -1em;"&gt;&lt;span&gt;for f in *&lt;br /&gt;do i=`echo $f|iconv -f gbk -t utf-8 -c`&lt;br /&gt;`mv $f $i`&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;grep mailto dispuser\(5* | sed '1,$s/.*mailto:\(.*\)\".*/\1/g'&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-5352649633674407983?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/5352649633674407983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=5352649633674407983' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5352649633674407983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5352649633674407983'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/bash-script-practice.html' title='bash script practice'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-1510218298173716884</id><published>2007-02-13T23:35:00.000+08:00</published><updated>2007-02-12T21:45:28.804+08:00</updated><title type='text'>gdesklets</title><content type='html'>http://www.gnome-look.org/content/show.php?content=13548&lt;br /&gt;http://blog.guoshuang.com/showlog.asp?cat_id=40&amp;amp;log_id=3821&lt;br /&gt;http://blog.vetcafe.net/2005/04/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-1510218298173716884?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/1510218298173716884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=1510218298173716884' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1510218298173716884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/1510218298173716884'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/gdesklets.html' title='gdesklets'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-4182335785094113586</id><published>2007-02-12T21:41:00.000+08:00</published><updated>2007-02-17T00:09:02.410+08:00</updated><title type='text'>make icewm look better</title><content type='html'>kk@kk-desktop:~$ grep ^[^#] .icewm/preferences&lt;br /&gt;UseMouseWheel=1 # 0/1&lt;br /&gt;TaskBarShowWorkspaces=0 # 0/1&lt;br /&gt;WorkspaceNames=" 1 ", " 2 ", " 3 ", " 4 "&lt;br /&gt;DesktopBackgroundImage="/home/kk/Firefox_wallpaper.png"&lt;br /&gt;&lt;br /&gt;kk@kk-desktop:~$ grep ^[^#] .icewm/startup&lt;br /&gt;/usr/bin/rox -p=wd &amp;amp;&lt;br /&gt;&lt;br /&gt;kk@kk-desktop:~$ ll .icewm/startup&lt;br /&gt;-rwxr-xr-x 1 kk kk 34 2007-02-12 21:14 .icewm/startup&lt;br /&gt;&lt;br /&gt;plug Section "Monitor" to enable the dpms(...? I supposed the default option is on, it doesn't need emphasize)&lt;br /&gt;Option "DPMS"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;then change the standby time in the  Section "ServerLayout" . I've no idea about the suspend and offtime, but the standby time works.&lt;br /&gt;&lt;br /&gt;&lt;code&gt; Option "StandbyTime"    "20"    # Turn off screen in 20 minutes&lt;br /&gt;Option "SuspendTime"    "30"    # Full hibernation in 30 minutes&lt;br /&gt;Option "OffTime"        "40"    # Turn off DPMS monitor&lt;br /&gt;&lt;br /&gt;I've to admit that I made a big mistake. Last time I read the manual in icewm it mention about the gnome-look setting icewm-gnome-config is recommended to install. But I tried and failed.&lt;br /&gt;This time I use startx instead of gdm to start icewm, the gnome-config works!&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-4182335785094113586?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/4182335785094113586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=4182335785094113586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4182335785094113586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/4182335785094113586'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/make-icewm-look-better.html' title='make icewm look better'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-8285481154013527521</id><published>2007-02-12T21:26:00.000+08:00</published><updated>2007-02-14T09:52:05.656+08:00</updated><title type='text'>~/.gtkrc-2.0 for icewm</title><content type='html'>&lt;span style="font-size:100%;"&gt;other not-gnome windows-manager may has font problem while using gtk user interface. saying ICEWM.&lt;br /&gt;to avoid this problem we should config some issue, :&lt;br /&gt;1. build a file ~/.gtkrc-2.0:&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;blockquote style="font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;    style "user-font"&lt;br /&gt;{&lt;br /&gt;#   font_name="Tahoma,SimSun 9"&lt;br /&gt;font_name="Bitstream Vera Sans, WenQuanYi Bitmap Song 12"&lt;br /&gt;}&lt;br /&gt;widget_class "*" style "user-font"&lt;br /&gt;&lt;br /&gt;gtk-font-name = "Bitstream Vera Sans, WenQuanYi Bitmap Song 12"&lt;br /&gt;#    gtk-theme-name = "Clearlooks-DeepSky"&lt;br /&gt;#    gtk-icon-theme-name = "Sude"&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:100%;"&gt;make sure the follow parameter works, and we can write this in ./Xsession&lt;br /&gt;&lt;/span&gt;&lt;pre&gt;&lt;blockquote style="font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt; export &lt;span class="highlightedSearchTerm"&gt;GTK&lt;/span&gt;2_RC_FILES="~/.&lt;span class="highlightedSearchTerm"&gt;gtk&lt;/span&gt;rc-2.0:$&lt;span class="highlightedSearchTerm"&gt;GTK&lt;/span&gt;2_RC_FILES"&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;and also, if we found that file doesn't work, we have to plug some sentence in it:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote style="font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;  # create temp file for X resources&lt;br /&gt;XRESOURCES=`mktemp /tmp/xrdb.XXXXXX`&lt;br /&gt;&lt;br /&gt;# Has to go prior to merging Xft.xrdb, as its the "Defaults" file&lt;br /&gt;#test -r $HOME/.Xdefaults &amp;&amp;amp; cat $HOME/.Xdefaults &gt;&gt; $XRESOURCES&lt;br /&gt;&lt;br /&gt;cat &gt;&gt; $XRESOURCES &lt;&lt;&gt;&gt; $XRESOURCES&lt;br /&gt;&lt;br /&gt;# load all X resources&lt;br /&gt;xrdb -nocpp -merge $XRESOURCES&lt;br /&gt;rm -f $XRESOURCES&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    #注：这段代码是从 xfce 的启动脚本里提取出来的。(/etc/xdg/xfce4/xinitrc)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;and if you are a left-hand and want the left and right key to be reserved, try this:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;xmodmap -e "pointer = 3 2 1" # 设置为惯用左手鼠标&lt;/blockquote&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-8285481154013527521?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/8285481154013527521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=8285481154013527521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8285481154013527521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8285481154013527521'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/gtkrc-20-for-icewm.html' title='~/.gtkrc-2.0 for icewm'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-8143904267268180072</id><published>2007-02-11T13:59:00.000+08:00</published><updated>2007-02-11T03:21:56.127+08:00</updated><title type='text'>how to play xmame with joystick</title><content type='html'>put this parameter in to the xmame config file&lt;br /&gt;jt              1&lt;br /&gt;jdev           /dev/input/js0&lt;br /&gt;usbpspad    1&lt;br /&gt;&lt;br /&gt;echo -n "jt              1&lt;br /&gt;jdev           /dev/input/js0&lt;br /&gt;usbpspad    1" &gt;&gt; ~/.xmame/xmamerc&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-8143904267268180072?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/8143904267268180072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=8143904267268180072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8143904267268180072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8143904267268180072'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/how-to-play-xmame-with-joystick.html' title='how to play xmame with joystick'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-9044448703185436170</id><published>2007-02-11T03:12:00.000+08:00</published><updated>2007-02-11T02:58:38.216+08:00</updated><title type='text'>what the hell is cp -a?</title><content type='html'>cp -a, the parameter -a include 3 parameter below&lt;br /&gt;       -R, -r, --recursive&lt;br /&gt;              copy directories recursively&lt;br /&gt;        -P, --no-dereference&lt;br /&gt;              never follow symbolic links&lt;br /&gt;       --preserve[=ATTR_LIST]&lt;br /&gt;              preserve   the   specified   attributes   (default:  mode,owner‐&lt;br /&gt;              ship,timestamps) and security contexts, if  possible  additional&lt;br /&gt;              attributes: links, all&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-9044448703185436170?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/9044448703185436170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=9044448703185436170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/9044448703185436170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/9044448703185436170'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/what-hell-is-cp.html' title='what the hell is cp -a?'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-818037554442996662</id><published>2007-02-11T02:50:00.000+08:00</published><updated>2007-02-12T21:39:48.232+08:00</updated><title type='text'>light GUI icewm+rox-filer</title><content type='html'>http://www.gnome-cn.org/documents/howto/set-default-gtk-font-theme/?searchterm=gtk%20%E5%AD%97%E4%BD%93%20%E5%B0%8F&lt;br /&gt;&lt;br /&gt;IceWm is a Window Manager for X Window System. It is fast and&lt;br /&gt;memory-efficient, and it provides many different looks including Windows'95,&lt;br /&gt;OS/2 Warp 3,4, Motif. It tries to take the best features of the above&lt;br /&gt;systems. Additional features include  multiple workspaces, opaque move/resize,&lt;br /&gt;task bar, window list, mailbox status, digital clock.&lt;br /&gt;ROX-Filer is a simple and easy to use graphical file manager&lt;br /&gt;for X11 based on the GTK2 library. It uses a uniform&lt;br /&gt;drag-and-drop approach for every operation.&lt;br /&gt;dpkg -L icewm and you should read the config file in /etc/X11/icewm location. Take these out of the folder and put it in home's corresponded position..&lt;br /&gt;About the file manager's file double clicking function, we can refer it from right click-set key function.   .&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-818037554442996662?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/818037554442996662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=818037554442996662' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/818037554442996662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/818037554442996662'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/light-gui-icewmrox-filer.html' title='light GUI icewm+rox-filer'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-3427625741909859486</id><published>2007-02-05T09:13:00.000+08:00</published><updated>2007-02-05T09:28:19.699+08:00</updated><title type='text'>backup your apt deb packages for local source</title><content type='html'>http://forum.ubuntu.org.cn/viewtopic.php?t=32554&lt;br /&gt;&lt;ul&gt;&lt;li&gt;create a packages index:&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;br /&gt;sudo apt-get install dpkg-dev&lt;br /&gt;sudo dpkg-scanpackages packs /dev/null |gzip &gt; packs/Packages.gz&lt;/blockquote&gt;&lt;ul&gt;&lt;li&gt;the source includes 4 kinds of different packages called main/restricted/universe/multiverse, we can find these in each site like this:&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt; main  “.....DIR”/packs/dists/edgy/main/binary-i386/&lt;br /&gt;restricted  “.....DIR”/packs/dists/edgy/restricted/binary-i386/&lt;br /&gt;universe  “.....DIR”/packs/dists/edgy/universe/binary-i386/&lt;br /&gt;multiverse  “.....DIR”/packs/dists/edgy/multiverse/binary-i386/&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;&lt;div style="text-align: center;"&gt;we have make sure the packages index "Packages.gz" in the right position,&lt;br /&gt;&lt;span class="postbody"&gt;put the packages.gz under the binary-i386 document and change the /etc/apt/source.list setting.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="postbody"&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="postbody"&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="postbody"&gt;link all your own packages to &lt;/span&gt;&lt;span class="postbody"&gt;/var/cache/apt/archives/&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-3427625741909859486?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/3427625741909859486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=3427625741909859486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3427625741909859486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/3427625741909859486'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/backup-your-apt-deb-packages-for-local.html' title='backup your apt deb packages for local source'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-2910316545131178862</id><published>2007-02-03T23:11:00.000+08:00</published><updated>2007-02-03T23:15:29.438+08:00</updated><title type='text'>conflict between scim and wine</title><content type='html'>scim 1.4.4-4ubuntu6&lt;br /&gt;wine   0.9.29-0ubuntu1~edgy1&lt;br /&gt;&lt;br /&gt;http://forum.ubuntu.org.cn/viewtopic.php?t=36322&amp;amp;highlight=scim+easy+wine&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-2910316545131178862?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/2910316545131178862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=2910316545131178862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2910316545131178862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2910316545131178862'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/conflict-between-scim-and-wine.html' title='conflict between scim and wine'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-7469430407714207272</id><published>2007-02-02T16:08:00.000+08:00</published><updated>2007-02-15T15:42:18.072+08:00</updated><title type='text'>a shell script for rename</title><content type='html'>&lt;blockquote&gt;i=1; for f in *; do mv $f ${i}.zip; (( i++ )); done&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;perl -le' $i = 1;foreach (@ARGV) { rename $_, $i++ }' *&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Advanced Bash-Scripting Guide&lt;br /&gt;http://www.linuxsir.org/main/doc/abs/abs3.7cnhtm/&lt;br /&gt;&lt;br /&gt;and for change the character code from gb2312 to utf-8:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;for f in *&lt;br /&gt;do i=`echo $f|iconv -f gbk -t utf-8 -c`&lt;br /&gt;`mv $f $i`&lt;br /&gt;done&lt;/blockquote&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-7469430407714207272?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/7469430407714207272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=7469430407714207272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/7469430407714207272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/7469430407714207272'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/shell-script-for-rename.html' title='a shell script for rename'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-5619402360881168086</id><published>2007-02-01T23:42:00.000+08:00</published><updated>2007-02-02T08:57:35.764+08:00</updated><title type='text'>Improve your chinese viewing</title><content type='html'>Almost all the guideline for chinese support must have this.&lt;br /&gt;&lt;blockquote&gt;sudo fontconfig-voodoo -f -s zh_CN&lt;/blockquote&gt;&lt;br /&gt;This step is not trivial to correctly display your characters of other language such as chinese, korean, japanese. In order to configure correctly, you must have the locale support. Like for example above, you must have zh_CN locale installed.&lt;br /&gt;List all fontconfig that you can configure.&lt;blockquote&gt;&lt;br /&gt;sudo fontconfig-voodoo -l&lt;/blockquote&gt;&lt;br /&gt;Check you current fontconfig,&lt;blockquote&gt;&lt;br /&gt;sudo fontconfig-voodoo -c&lt;/blockquote&gt;It's equal to following:&lt;br /&gt;&lt;br /&gt;sudo ln -sf /usr/share/language-selector/fontconfig/zh_CN /etc/fonts/language-selector.conf&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;check the /etc/font/fonts.conf, the below sentance explain  the job of the /etc/fonts/language-selector.conf &lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;!--   Load local ubuntu-specific language custom file --&gt;&lt;br /&gt;      &lt;include ignore_missing="yes"&gt;language-selector.conf&lt;/include&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-5619402360881168086?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/5619402360881168086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=5619402360881168086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5619402360881168086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/5619402360881168086'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/02/improve-your-chinese-viewing.html' title='Improve your chinese viewing'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-7886337241171861123</id><published>2007-01-30T10:08:00.000+08:00</published><updated>2007-01-30T11:27:07.425+08:00</updated><title type='text'>Vim Commands Cheat Sheet</title><content type='html'>&lt;a name="exit"&gt;&lt;h2&gt;How to Exit&lt;/h2&gt;&lt;/a&gt;&lt;p&gt; &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;:q[uit]&lt;/td&gt;     &lt;td&gt;Quit Vim.  This fails when changes have been made.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:q[uit]!&lt;/td&gt;     &lt;td&gt;Quit without writing.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:cq[uit]&lt;/td&gt;     &lt;td&gt;Quit always, without writing.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:wq&lt;/td&gt;     &lt;td&gt;Write the current file and exit.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:wq!&lt;/td&gt;     &lt;td&gt;Write the current file and exit always.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:wq {file}&lt;/td&gt;     &lt;td&gt;Write to {file}.  Exit if not editing the last&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:wq! {file}&lt;/td&gt;     &lt;td&gt;Write to {file} and exit always.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]wq[!]&lt;/td&gt;     &lt;td&gt;[file]  Same as above, but only write the lines in [range].&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;ZZ&lt;/td&gt;     &lt;td&gt;Write current file, if modified, and exit.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;ZQ&lt;/td&gt;     &lt;td&gt;Quit current file and exit (same as ":q!").&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="edit"&gt;&lt;h2&gt;Editing a File&lt;/h2&gt;&lt;/a&gt;&lt;p&gt; &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;:e[dit]&lt;/td&gt;     &lt;td&gt;Edit the current file.  This is useful to re-edit the current file, when it has been changed outside of Vim.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:e[dit]!&lt;/td&gt;     &lt;td&gt;Edit the current file always.  Discard any changes to the current buffer.  This is useful if you want to start all over again.&lt;/td&gt;   &lt;/tr&gt;    &lt;tr&gt;     &lt;td&gt;:e[dit] {file}&lt;/td&gt;     &lt;td&gt;Edit {file}.  &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:e[dit]! {file}&lt;/td&gt;     &lt;td&gt;Edit {file} always.  Discard any changes to the current buffer.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;gf&lt;/td&gt;     &lt;td&gt;Edit the file whose name is under or after the cursor.  Mnemonic: "goto file".&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;/p&gt;&lt;hr /&gt;&lt;a name="insert"&gt;&lt;h2&gt;Inserting Text&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;a&lt;/td&gt;     &lt;td&gt;Append text after the cursor [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;A&lt;/td&gt;     &lt;td&gt;Append text at the end of the line [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;i&lt;/td&gt;     &lt;td&gt;Insert text before the cursor [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;I&lt;/td&gt;     &lt;td&gt;Insert text before the first non-blank in the line [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;gI&lt;/td&gt;     &lt;td&gt;Insert text in column 1 [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;o&lt;/td&gt;     &lt;td&gt;Begin a new line below the cursor and insert text, repeat [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;O&lt;/td&gt;     &lt;td&gt;Begin a new line above the cursor and insert text, repeat [count] times.&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;h2&gt;Inserting a file&lt;/h2&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;:r[ead] [name]&lt;/td&gt;     &lt;td&gt;Insert the file [name] below the cursor.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:r[ead] !{cmd}&lt;/td&gt;     &lt;td&gt;Execute {cmd} and insert its standard output below the cursor. &lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="delete"&gt;&lt;h2&gt;Deleting Text&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;&lt;&gt; or&lt;br /&gt;x&lt;/td&gt;     &lt;td&gt;Delete [count] characters under and after the cursor&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;X&lt;/td&gt;     &lt;td&gt;Delete [count] characters before the cursor&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;d{motion}&lt;/td&gt;     &lt;td&gt;Delete text that {motion} moves over &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;dd&lt;/td&gt;     &lt;td&gt;Delete [count] lines&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;D&lt;/td&gt;     &lt;td&gt;Delete the characters under the cursor until the end of the line&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{Visual}x  or&lt;br /&gt;{Visual}d&lt;/td&gt;     &lt;td&gt;Delete the highlighted text (for {Visual} see &lt;a href="http://www.fprintf.net/vimCheatSheet.html#select"&gt;Selecting Text&lt;/a&gt;).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{Visual}CTRL-H   or&lt;br /&gt;{Visual}&lt;bs&gt;&lt;/bs&gt;&lt;/td&gt;     &lt;td&gt;When in Select mode: Delete the highlighted text&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{Visual}X  or&lt;br /&gt;{Visual}D&lt;/td&gt;     &lt;td&gt;Delete the highlighted lines &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]d[elete]&lt;/td&gt;     &lt;td&gt;Delete [range] lines (default: current line)&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]d[elete] {count}&lt;/td&gt;     &lt;td&gt;Delete {count} lines, starting with [range]&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="replace"&gt;&lt;h2&gt;Changing (or Replacing) Text&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;r{char}&lt;/td&gt;     &lt;td&gt;replace the character under the cursor with {char}.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;R&lt;/td&gt;     &lt;td&gt;Enter Insert mode, replacing characters rather than inserting&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;~&lt;/td&gt;     &lt;td&gt;Switch case of the character under the cursor and move the cursor to the right.  If a [count] is given, do that many characters.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;~{motion}&lt;/td&gt;     &lt;td&gt;switch case of {motion} text.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{Visual}~&lt;/td&gt;     &lt;td&gt;Switch case of highlighted text&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="substitute"&gt;&lt;h2&gt;Substituting&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;:[range]s[ubstitute]/{pattern}/{string}/[c][e][g][p][r][i][I] [count]&lt;/td&gt;     &lt;td&gt;For each line in [range] replace a match of {pattern} with     {string}.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]s[ubstitute] [c][e][g][r][i][I] [count] :[range]&amp;[c][e][g][r][i][I] [count]&lt;/td&gt;     &lt;td&gt;Repeat last :substitute with same search pattern and substitute string, but without the same flags.  You may add extra flags&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;pre&gt;The arguments that you can use for the substitute commands:&lt;br /&gt;[c]  Confirm each substitution.  Vim positions the cursor on the matching&lt;br /&gt; string.  You can type:&lt;br /&gt;     'y'      to substitute this match&lt;br /&gt;     'n'      to skip this match&lt;br /&gt;     &lt;esc&gt;   to skip this match&lt;br /&gt;     'a'      to substitute this and all remaining matches {not in Vi}&lt;br /&gt;     'q'      to quit substituting {not in Vi}&lt;br /&gt;     CTRL-E  to scroll the screen up {not in Vi}&lt;br /&gt;     CTRL-Y  to scroll the screen down {not in Vi}.&lt;br /&gt;[e]     When the search pattern fails, do not issue an error message and, in&lt;br /&gt; particular, continue in maps as if no error occurred. &lt;br /&gt;[g]  Replace all occurrences in the line.  Without this argument,&lt;br /&gt; replacement occurs only for the first occurrence in each line.&lt;br /&gt;[i]  Ignore case for the pattern. &lt;br /&gt;[I]  Don't ignore case for the pattern. &lt;br /&gt;[p]  Print the line containing the last substitute.&lt;br /&gt;&lt;/esc&gt;&lt;/pre&gt;  &lt;hr /&gt;&lt;a name="move"&gt;&lt;h2&gt;Copying and Moving Text&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;"{a-zA-Z0-9.%#:-"}&lt;/td&gt;     &lt;td&gt;Use register {a-zA-Z0-9.%#:-"} for next delete, yank or put (use uppercase character to append with delete and yank) ({.%#:} only work with put).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:reg[isters]&lt;/td&gt;     &lt;td&gt;Display the contents of all numbered and named registers.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:reg[isters] {arg}&lt;/td&gt;     &lt;td&gt;Display the contents of the numbered and named registers that are mentioned in {arg}.  &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:di[splay] [arg]&lt;/td&gt;     &lt;td&gt;Same as :registers. &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]y{motion}&lt;/td&gt;     &lt;td&gt;Yank {motion} text [into register x].&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]yy&lt;/td&gt;     &lt;td&gt;Yank [count] lines [into register x]&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]Y&lt;/td&gt;     &lt;td&gt;yank [count] lines [into register x] (synonym for yy).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{Visual}["x]y&lt;/td&gt;     &lt;td&gt;Yank the highlighted text [into register x] (for {Visual} see &lt;a href="http://www.fprintf.net/vimCheatSheet.html#select"&gt;Selecting Text&lt;/a&gt;).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{Visual}["x]Y&lt;/td&gt;     &lt;td&gt;Yank the highlighted lines [into register x]&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]y[ank] [x]&lt;/td&gt;     &lt;td&gt;Yank [range] lines [into register x].&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]y[ank] [x] {count}&lt;/td&gt;     &lt;td&gt;Yank {count} lines, starting with last line number in [range] (default: current line), [into register x].&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]p&lt;/td&gt;     &lt;td&gt;Put the text [from register x] after the cursor [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]P&lt;/td&gt;     &lt;td&gt;Put the text [from register x] before the cursor [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]gp&lt;/td&gt;     &lt;td&gt;Just like "p", but leave the cursor just after the new text.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;["x]gP&lt;/td&gt;     &lt;td&gt;Just like "P", but leave the cursor just after the new text.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[line]pu[t] [x]&lt;/td&gt;     &lt;td&gt;Put the text [from register x] after [line] (default current     line).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[line]pu[t]! [x]&lt;/td&gt;     &lt;td&gt;Put the text [from register x] before [line] (default current     line).&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="undo"&gt;&lt;h2&gt;Undo/Redo/Repeat&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;u&lt;/td&gt;     &lt;td&gt;Undo [count] changes. &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:u[ndo]&lt;/td&gt;     &lt;td&gt;Undo one change. &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;CTRL-R&lt;/td&gt;     &lt;td&gt;Redo [count] changes which were undone. &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:red[o]&lt;/td&gt;     &lt;td&gt;Redo one change which was undone. &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;U&lt;/td&gt;     &lt;td&gt;Undo all latest changes on one line.  {Vi: while not moved off of     it}&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;.&lt;/td&gt;     &lt;td&gt;Repeat last change, with count replaced with [count].&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="motion"&gt;&lt;h2&gt;Moving Around&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;/p&gt;&lt;pre&gt;Basic motion commands:&lt;br /&gt;&lt;br /&gt;       k              &lt;up&gt;&lt;br /&gt;     h   l      &lt;left&gt;    &lt;right&gt;&lt;br /&gt;       j             &lt;down&gt; &lt;/down&gt;&lt;/right&gt;&lt;/left&gt;&lt;/up&gt;&lt;/pre&gt;  &lt;p&gt; &lt;/p&gt;&lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;h  or&lt;br /&gt;&lt;left&gt;&lt;/left&gt;&lt;/td&gt;     &lt;td&gt;[count] characters to the left (exclusive).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;l or&lt;br /&gt;&lt;right&gt; or&lt;br /&gt;&lt;space&gt;&lt;/space&gt;&lt;/right&gt;&lt;/td&gt;     &lt;td&gt;[count] characters to the right (exclusive).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;k  or&lt;br /&gt;&lt;up&gt; or&lt;br /&gt;CTRL-P&lt;/up&gt;&lt;/td&gt;     &lt;td&gt;[count] lines upward&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;j or&lt;br /&gt;&lt;down&gt; or&lt;br /&gt;CTRL-J or&lt;br /&gt;&lt;nl&gt; or&lt;br /&gt;CTRL-N&lt;/nl&gt;&lt;/down&gt;&lt;/td&gt;     &lt;td&gt;[count] lines downward (linewise).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;0&lt;/td&gt;     &lt;td&gt;To the first character of the line (exclusive). &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;home&gt;&lt;/td&gt;     &lt;td&gt;To the first character of the line (exclusive). &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;^&lt;/td&gt;     &lt;td&gt;To the first non-blank character of the line&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;$  or&lt;br /&gt;&lt;end&gt;&lt;/td&gt;     &lt;td&gt;To the end of the line and [count - 1] lines downward&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;g0 or&lt;br /&gt;g&lt;home&gt;&lt;/td&gt;     &lt;td&gt;When lines wrap ('wrap on): To the first character of the screen line (exclusive). Differs from "0" when a line is wider than the screen. When lines don't wrap ('wrap' off): To the leftmost character of the current line that is on the screen. Differs from "0" when the first character of the line is not on the screen.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;g^&lt;/td&gt;     &lt;td&gt;When lines wrap ('wrap' on): To the first non-blank character of the screen line (exclusive). Differs from "^" when a line is wider than the screen. When lines don't wrap ('wrap' off): To the leftmost non-blank character of the current line that is on the screen. Differs from "^" when the first non-blank character of the line is not on the screen. &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;g$ or&lt;br /&gt;g&lt; end&amp;amp;gr;&lt;/td&gt;     &lt;td&gt;When lines wrap ('wrap' on): To the last character of the screen line and [count - 1] screen lines downward (inclusive). Differs from "$" when a line is wider than the screen. When lines don't wrap ('wrap' off): To the rightmost character of the current line that is visible on the screen. Differs from "$" when the last character of the line is not on the screen or when a count is used.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;f{char}&lt;/td&gt;     &lt;td&gt;To [count]'th occurrence of {char} to the right.  The cursor is placed on {char} (inclusive).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;F{char}&lt;/td&gt;     &lt;td&gt;To the [count]'th occurrence of {char} to the left.  The cursor is placed on {char} (inclusive).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;t{char}&lt;/td&gt;     &lt;td&gt;Till before [count]'th occurrence of {char} to the right.  The cursor is placed on the character left of {char} (inclusive).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;T{char}&lt;/td&gt;     &lt;td&gt;Till after [count]'th occurrence of {char} to the left.  The cursor is placed on the character right of {char} (inclusive).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;;&lt;/td&gt;     &lt;td&gt;Repeat latest f, t, F or T [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;,&lt;/td&gt;     &lt;td&gt;Repeat latest f, t, F or T in opposite direction [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;-  &lt;minus&gt;&lt;/td&gt;     &lt;td&gt;[count] lines upward, on the first non-blank character     (linewise).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;+ or&lt;br /&gt;CTRL-M or&lt;br /&gt;&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;[count] lines downward, on the first non-blank character     (linewise).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;_  &lt;underscore&gt;&lt;/td&gt;     &lt;td&gt;[count] - 1 lines downward, on the first non-blank character (linewise).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;c-end&gt; or&lt;br /&gt;G&lt;/td&gt;     &lt;td&gt;Goto line [count], default last line, on the first non-blank character.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;c-home&gt;  or&lt;br /&gt;gg&lt;/td&gt;     &lt;td&gt;Goto line [count], default first line, on the first non-blank character.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;s-right&gt;  or&lt;br /&gt;w&lt;/td&gt;     &lt;td&gt;[count] words forward &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;c-right&gt;  or&lt;br /&gt;W&lt;/td&gt;     &lt;td&gt;[count] WORDS forward &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;e&lt;/td&gt;     &lt;td&gt;Forward to the end of word [count] &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;E&lt;/td&gt;     &lt;td&gt;Forward to the end of WORD [count] &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;s-left&gt;  or&lt;br /&gt;b&lt;/td&gt;     &lt;td&gt;[count] words backward &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;c-left&gt;  or&lt;br /&gt;B&lt;/td&gt;     &lt;td&gt;[count] WORDS backward &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;ge&lt;/td&gt;     &lt;td&gt;Backward to the end of word [count] &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;gE&lt;/td&gt;     &lt;td&gt;Backward to the end of WORD [count]&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; These commands move over words or WORDS. &lt;p&gt;A word consists of a sequence of letters, digits and underscores, or a sequence of other non-blank characters, separated with white space (spaces, tabs, &lt;eol&gt;).  This can be changed with the 'iskeyword' option.&lt;/eol&gt;&lt;/p&gt; &lt;p&gt;A WORD consists of a sequence of non-blank characters, separated with white space.  An empty line is also considered to be a word and a WORD.&lt;/p&gt; &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;(&lt;/td&gt;     &lt;td&gt;[count] sentences backward&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;)&lt;/td&gt;     &lt;td&gt;[count] sentences forward &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;{&lt;/td&gt;     &lt;td&gt;[count] paragraphs backward&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;}&lt;/td&gt;     &lt;td&gt;[count] paragraphs forward &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;]]&lt;/td&gt;     &lt;td&gt;[count] sections forward or to the next '{' in the first column.  When used after an operator, then the '}' in the first column.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;][&lt;/td&gt;     &lt;td&gt;[count] sections forward or to the next '}' in the first column &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;[[&lt;/td&gt;     &lt;td&gt;[count] sections backward or to the previous '{' in the first     column&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;[]&lt;/td&gt;     &lt;td&gt;[count] sections backward or to the previous '}' in the first column     &lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;hr /&gt;&lt;a name="marks"&gt;&lt;h2&gt;Marks&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;m{a-zA-Z}&lt;/td&gt;     &lt;td&gt;Set mark {a-zA-Z} at cursor position (does not move the cursor, this is not a motion command).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;m'  or&lt;br /&gt;m`&lt;/td&gt;     &lt;td&gt;Set the previous context mark. This can be jumped to with the "''" or "``" command (does not move the cursor, this is not a motion command).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]ma[rk] {a-zA-Z}&lt;/td&gt;     &lt;td&gt;Set mark {a-zA-Z} at last line number in [range], column 0.  Default is cursor line.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:[range]k{a-zA-Z}&lt;/td&gt;     &lt;td&gt;Same as :mark, but the space before the mark name can be omitted.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;'{a-z}&lt;/td&gt;     &lt;td&gt;To the first non-blank character on the line with mark {a-z} (linewise).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;'{A-Z0-9}&lt;/td&gt;     &lt;td&gt;To the first non-blank character on the line with mark {A-Z0-9} in the correct file&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;`{a-z}&lt;/td&gt;     &lt;td&gt;To the mark {a-z}&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;`{A-Z0-9}&lt;/td&gt;     &lt;td&gt;To the mark {A-Z0-9} in the correct file&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:marks&lt;/td&gt;     &lt;td&gt;List all the current marks (not a motion command).&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:marks {arg}&lt;/td&gt;     &lt;td&gt;List the marks that are mentioned in {arg} (not a motion command).  For example:&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="search"&gt;&lt;h2&gt;Searching&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;/{pattern}[/]&lt;cr&gt;&lt;/cr&gt;&lt;/td&gt;     &lt;td&gt;Search forward for the [count]'th occurrence of {pattern}&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;/{pattern}/{offset}&lt;cr&gt;&lt;/cr&gt;&lt;/td&gt;     &lt;td&gt;Search forward for the [count]'th occurrence of {pattern} and go {offset} lines up or down.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;/&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;Search forward for the [count]'th latest used pattern&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;//{offset}&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;Search forward for the [count]'th latest used pattern with new.  If {offset} is empty no offset is used.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;?{pattern}[?]&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;Search backward for the [count]'th previous occurrence of {pattern}     &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;?{pattern}?{offset}&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;Search backward for the [count]'th previous occurrence of {pattern} and go {offset} lines up or down &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;?&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;Search backward for the [count]'th latest used pattern &lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;??{offset}&lt;cr&gt;&lt;/td&gt;     &lt;td&gt;Search backward for the [count]'th latest used pattern with new {offset}.  If {offset} is empty no offset is used.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;n&lt;/td&gt;     &lt;td&gt;Repeat the latest "/" or "?" [count] times.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;N&lt;/td&gt;     &lt;td&gt;Repeat the latest "/" or "?" [count] times in opposite direction.     &lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;&lt;hr /&gt;&lt;a name="select"&gt;&lt;h2&gt;Selecting Text (Visual Mode)&lt;/h2&gt;&lt;/a&gt;&lt;p&gt;  &lt;/p&gt;&lt;p&gt;To select text, enter visual mode with one of the commands below, and use &lt;a href="http://www.fprintf.net/vimCheatSheet.html#motion"&gt;motion commands&lt;/a&gt; to highlight the text you are interested in.  Then, use some command on the text. &lt;/p&gt; &lt;pre&gt;The operators that can be used are:&lt;br /&gt; ~  switch case&lt;br /&gt; d  delete&lt;br /&gt; c  change&lt;br /&gt; y  yank&lt;br /&gt; &gt;  shift right&lt;br /&gt; &lt;  shift left&lt;br /&gt; !  filter through external command&lt;br /&gt; =  filter through 'equalprg' option command&lt;br /&gt; gq  format lines to 'textwidth' length&lt;br /&gt;&lt;/pre&gt;  &lt;table border="3" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;v&lt;/td&gt;     &lt;td&gt;start Visual mode per character.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;V&lt;/td&gt;     &lt;td&gt;start Visual mode linewise.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;&lt;esc&gt;&lt;/td&gt;     &lt;td&gt;exit Visual mode without making any changes&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;hr /&gt;&lt;a name="suspend"&gt;&lt;h2&gt;How to Suspend&lt;/h2&gt;&lt;/a&gt;     &lt;table border="3" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;CTRL-Z&lt;/td&gt;     &lt;td&gt;Suspend Vim, like ":stop". Works in Normal and in Visual mode. In Insert and Command-line mode, the CTRL-Z is inserted as a normal character.&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;     &lt;td&gt;:sus[pend][!]  or&lt;br /&gt;:st[op][!]&lt;/td&gt;     &lt;td&gt;Suspend Vim. If the '!' is not given and 'autowrite' is set, every buffer with changes and a file name is written out. If the '!' is given or 'autowrite' is not set, changed buffers are not written, don't forget to bring Vim back to the foreground later!&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-7886337241171861123?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/7886337241171861123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=7886337241171861123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/7886337241171861123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/7886337241171861123'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/vim.html' title='Vim Commands Cheat Sheet'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-6996341454318900767</id><published>2007-01-29T22:41:00.000+08:00</published><updated>2007-01-29T22:43:52.407+08:00</updated><title type='text'>easywine</title><content type='html'>deb package for ubuntu&lt;br /&gt;deb http://archive.ubuntu.org.cn/ubuntu-cn edgy main universe multiverse restricted&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-6996341454318900767?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/6996341454318900767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=6996341454318900767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/6996341454318900767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/6996341454318900767'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/easywine.html' title='easywine'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-8370021141880016604</id><published>2007-01-28T01:26:00.001+08:00</published><updated>2007-01-28T01:26:49.751+08:00</updated><title type='text'>Beryl @ Edgy with nVIDIA Driver</title><content type='html'>http://my.opera.com/anguste/blog/index.dml/tag/Edgy&lt;br /&gt;Monday, 25. December 2006, 09:23:37&lt;br /&gt;&lt;br /&gt;Driver, Edgy, ubuntu, Linux ...&lt;br /&gt;有这样几篇文章可以参考：&lt;br /&gt;http://wiki.beryl-project.org/index.php/Install/Ubuntu/Edgy/nVIDIA&lt;br /&gt;http://www.ubuntuforums.org/showthread.php?t=263851&lt;br /&gt;http://doc.gwos.org/index.php/BerylOnEdgy&lt;br /&gt;&lt;br /&gt;略简单概括：&lt;br /&gt;&lt;br /&gt;添加sources&lt;br /&gt;&lt;br /&gt;sudo gedit /etc/apt/sources.list&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;加入如下两个&lt;br /&gt;&lt;br /&gt;    deb http://ubuntu.beryl-project.org edgy main&lt;br /&gt;    deb http://nvidia.limitless.lupine.me.uk/ubuntu edgy stable&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;运行命令获取key&lt;br /&gt;&lt;br /&gt;wget http://ubuntu.beryl-project.org/root@lupine.me.uk.gpg -O- | sudo apt-key add -&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;完成以后还是老规矩&lt;br /&gt;&lt;br /&gt;sudo apt-get update&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;下载安装nVIDIA驱动&lt;br /&gt;&lt;br /&gt;sudo apt-get install nvidia-glx&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;过程中会提示同时更新linux-restricted-modules和linux-restricted-modules-common的包，反正也不大。&lt;br /&gt;&lt;br /&gt;由于restricted modules的变更，在完成后需要再次升级一下&lt;br /&gt;&lt;br /&gt;sudo apt-get upgrade&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;然后可以配置X&lt;br /&gt;&lt;br /&gt;sudo nvidia-xconfig&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;需要开启Composite&lt;br /&gt;&lt;br /&gt;sudo gedit /etc/X11/xorg.conf&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;在Screen模块下添加一行&lt;br /&gt;&lt;br /&gt;    Option "AddARGBGLXVisuals" "True"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;在Device模块下添加一行&lt;br /&gt;&lt;br /&gt;    Option "TripleBuffer" "True"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;完成之后重启，驱动就算装好了。&lt;br /&gt;&lt;br /&gt;随后安装Beryl&lt;br /&gt;&lt;br /&gt;sudo apt-get install beryl-core beryl-plugins beryl-plugins-data emerald beryl-settings beryl-manager beryl beryl-dev emerald-themes&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;在System-Preferences-Sessions的Startup项中加入beryl-manager就可以在每次启动时运行Beryl了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-8370021141880016604?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/8370021141880016604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=8370021141880016604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8370021141880016604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/8370021141880016604'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/beryl-edgy-with-nvidia-driver.html' title='Beryl @ Edgy with nVIDIA Driver'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-2328381674336909118</id><published>2007-01-28T00:32:00.000+08:00</published><updated>2007-01-28T00:34:22.435+08:00</updated><title type='text'>remove the "update-manager"</title><content type='html'>rm -f /root/etc/xdg/autostart/update-notifier.desktop&lt;br /&gt;rm -f /root/usr/share/autostart/adept_notifier_auto.desktop&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-2328381674336909118?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/2328381674336909118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=2328381674336909118' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2328381674336909118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2328381674336909118'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/remove-update-manager.html' title='remove the &quot;update-manager&quot;'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-2406298201889376768</id><published>2007-01-25T08:57:00.000+08:00</published><updated>2007-01-25T09:38:31.206+08:00</updated><title type='text'>colourshell.sh</title><content type='html'>&lt;pre&gt;# colourshell.sh&lt;br /&gt;&lt;br /&gt;# Please copy these into a file named .colourshell.sh at home. Then plus ". .colourshell.sh"&lt;br /&gt;# to the the .bashrc.&lt;br /&gt;&lt;br /&gt;# In an interactive Bash shell, cycles through a sequence of colours,&lt;br /&gt;# one per command, so that you can more easily see where one finishes&lt;br /&gt;# and the next starts.&lt;br /&gt;&lt;br /&gt;# (C) 2006 Philip Endecott&lt;br /&gt;# See http://chezphil.org/colourshell/ for more information.&lt;br /&gt;&lt;br /&gt;# This program is free software; you can redistribute it and/or modify&lt;br /&gt;# it under the terms of the GNU General Public License as published by&lt;br /&gt;# the Free Software Foundation; either version 2 of the License, or&lt;br /&gt;# any later version.&lt;br /&gt;#&lt;br /&gt;# This program is distributed in the hope that it will be useful,&lt;br /&gt;# but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;# GNU General Public License for more details.&lt;br /&gt;#&lt;br /&gt;# You should have received a copy of the GNU General Public License&lt;br /&gt;# along with this program; if not, write to the Free Software&lt;br /&gt;# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# As far as I'm aware this won't work in any shells other than bash&lt;br /&gt;# because it uses bash-specific features.&lt;br /&gt;&lt;br /&gt;# To try it out, source this file into an interactive shell:&lt;br /&gt;# source /path/to/colourshell.sh&lt;br /&gt;&lt;br /&gt;# For permanent use this file should be sourced from your bash startup&lt;br /&gt;# script(s).&lt;br /&gt;#&lt;br /&gt;# Bash may execute various different startup scripts; see the&lt;br /&gt;# INVOCATION section of the bash man page for details.  To have this&lt;br /&gt;# script called for both login shells (e.g. virtual consoles) and&lt;br /&gt;# non-login shells (e.g. xterms) you need to call it from both&lt;br /&gt;# .bash_profile and .bashrc.  .bashrc may also be called for&lt;br /&gt;# non-interactive shells; to avoid running this in that case you can&lt;br /&gt;# enclose the source command in an if block that tests for&lt;br /&gt;# interactivity by checking for PS1:&lt;br /&gt;#&lt;br /&gt;# if [ "$PS1" ]&lt;br /&gt;# then&lt;br /&gt;#   source /path/to/colourshell.sh&lt;br /&gt;# fi&lt;br /&gt;&lt;br /&gt;# Source this from somewhere near the end of those files.  In&lt;br /&gt;# particular, source it from after any code that sets the prompt&lt;br /&gt;# variables (PS1 etc.) since this code adds its stuff to the existing&lt;br /&gt;# PS1 setting.&lt;br /&gt;&lt;br /&gt;# If your startup scripts don't set PS1 to PS4, things could get&lt;br /&gt;# interesting if you start one shell inside another: this code will be&lt;br /&gt;# called twice!  It should still work, but ideally this script would&lt;br /&gt;# scrub any existing colour-setting codes from the prompts before&lt;br /&gt;# adding its own.&lt;br /&gt;&lt;br /&gt;# This code generates colour-changing escape sequences using the tput&lt;br /&gt;# program.  This is a simple utility that uses the termcap database to&lt;br /&gt;# look up escape sequences for the current terminal.  It seems to be&lt;br /&gt;# included in the major Linux distributions.  For details, see "man&lt;br /&gt;# tput" and "man 5 terminfo".  In particular see the "Color Handling"&lt;br /&gt;# section of "man 5 terminfo".&lt;br /&gt;&lt;br /&gt;# Most terminals with colour support have 8 colours.  An exception is&lt;br /&gt;# rxvt-unicode (and other rxvts?) which claims to have 88.  This script&lt;br /&gt;# doesn't know what to do with any other cases, so gives up immediately&lt;br /&gt;# without error.&lt;br /&gt;&lt;br /&gt;ncolours=`tput colors`&lt;br /&gt;case $ncolours in&lt;br /&gt;8) ;;&lt;br /&gt;88) ;;&lt;br /&gt;*) return 0 ;;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;# The following are the standard colour codes; see "man 5 terminfo".&lt;br /&gt;&lt;br /&gt;setaf_black=`tput setaf 0`&lt;br /&gt;setaf_blue=`tput setaf 1`&lt;br /&gt;setaf_green=`tput setaf 2`&lt;br /&gt;setaf_cyan=`tput setaf 3`&lt;br /&gt;setaf_red=`tput setaf 4`&lt;br /&gt;setaf_magenta=`tput setaf 5`&lt;br /&gt;setaf_yellow=`tput setaf 6`&lt;br /&gt;setaf_white=`tput setaf 7`&lt;br /&gt;&lt;br /&gt;# For 88-colour rxvt-unicode these 8 colours are near-enough right.&lt;br /&gt;# Try something like this to see the available colours:&lt;br /&gt;#&lt;br /&gt;# i=0&lt;br /&gt;# while true&lt;br /&gt;# do&lt;br /&gt;#   tput setaf $i&lt;br /&gt;#   echo "$i: Hello World"&lt;br /&gt;#   i=$(($i+1))&lt;br /&gt;# done&lt;br /&gt;&lt;br /&gt;# Define the colours to use.&lt;br /&gt;# Set prompt_colour to the escape sequence for the colour to use for&lt;br /&gt;# the prompt, and cmd_colours (an array) to the escape sequences for&lt;br /&gt;# the colours to use for the commands, in turn.&lt;br /&gt;&lt;br /&gt;declare -a cmd_colours&lt;br /&gt;&lt;br /&gt;# A complicating factor is that we don't know whether this terminal&lt;br /&gt;# has a white / light-coloured background or a black / dark-coloured&lt;br /&gt;# background.  This should influence our choice of colours.&lt;br /&gt;&lt;br /&gt;# Here is a heuristic: virtual consoles have TERM=linux and are&lt;br /&gt;# white-on-black, while X terminals and similar have TERM=xterm and&lt;br /&gt;# are black-on-white.&lt;br /&gt;&lt;br /&gt;case $TERM in&lt;br /&gt;linux)   background=dark ;;&lt;br /&gt;*xterm*) background=light ;;&lt;br /&gt;*)       background=light ;;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;# Choose colours, based on the guessed background colour:&lt;br /&gt;&lt;br /&gt;case $background in&lt;br /&gt;dark)  prompt_colour=$setaf_white&lt;br /&gt;      cmd_colours=($setaf_cyan $setaf_magenta $setaf_yellow) ;;&lt;br /&gt;light) prompt_colour=$setaf_black&lt;br /&gt;      cmd_colours=($setaf_blue $setaf_green $setaf_red) ;;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;# This variable tracks which command colour is currently in use:&lt;br /&gt;&lt;br /&gt;declare -i cmd_colour_index=-1&lt;br /&gt;&lt;br /&gt;# This function increments cmd_colour_index modulo the number of&lt;br /&gt;# command colours:&lt;br /&gt;&lt;br /&gt;function next_colour() {&lt;br /&gt; cmd_colour_index=$(( ($cmd_colour_index+1) % (${#cmd_colours[*]}) ))&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# PROMPT_COMMAND is a bash builtin variable that names a command to&lt;br /&gt;# run before each prompt.  (This will override any existing use of&lt;br /&gt;# this variable; how can multiple commands be chained together?)&lt;br /&gt;&lt;br /&gt;PROMPT_COMMAND=next_colour&lt;br /&gt;&lt;br /&gt;# This function returns the escape sequence for the current command&lt;br /&gt;# colour, from the array defined above:&lt;br /&gt;&lt;br /&gt;function cmd_colour() {&lt;br /&gt; echo ${cmd_colours[$cmd_colour_index]}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Define the prompt variables.  For each one we encapsulate the&lt;br /&gt;# current setting between a prefix and a suffix; the prefix sets the&lt;br /&gt;# colour for the prompt and the suffix sets the colour for the&lt;br /&gt;# command.&lt;br /&gt;&lt;br /&gt;# \[ ... \] are used around non-printing characters and are needed so&lt;br /&gt;# that Bash correctly calculates the screen position.  Functions can&lt;br /&gt;# be called using `...`, as long as the promptvars option is enabled:&lt;br /&gt;&lt;br /&gt;shopt -s promptvars&lt;br /&gt;&lt;br /&gt;prompt_prefix="\\[${prompt_colour}\\]"&lt;br /&gt;prompt_suffix='\[`cmd_colour`\]'&lt;br /&gt;&lt;br /&gt;PS1="${prompt_prefix}${PS1}${prompt_suffix}"&lt;br /&gt;PS2="${prompt_prefix}${PS2}${prompt_suffix}"&lt;br /&gt;PS3="${prompt_prefix}${PS3}${prompt_suffix}"&lt;br /&gt;PS4="${prompt_prefix}${PS4}${prompt_suffix}"&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-2406298201889376768?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/2406298201889376768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=2406298201889376768' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2406298201889376768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/2406298201889376768'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/colourshellsh.html' title='colourshell.sh'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116945812282164195</id><published>2007-01-22T17:26:00.000+08:00</published><updated>2007-01-22T17:28:43.326+08:00</updated><title type='text'>remove the volumn icon on desktop</title><content type='html'>gconf-editor&lt;br /&gt;&lt;br /&gt;apps-&gt;nautilus-&gt;desktop-&gt;volumes_visible&lt;br /&gt;3:03 PM 我给你找找最简单的&lt;br /&gt;&lt;br /&gt;sudo perl -pi -e 's/=.*/=GNOME;Applications;Settings/ if /^Categories/; s/^/#/ if /^NoDisplay/' /usr/share/applications/gconf-editor.desktop&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116945812282164195?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116945812282164195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116945812282164195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116945812282164195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116945812282164195'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/remove-volumn-icon-on-desktop.html' title='remove the volumn icon on desktop'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116839553135450320</id><published>2007-01-10T10:17:00.000+08:00</published><updated>2007-01-10T10:18:51.556+08:00</updated><title type='text'>new im tool for qq protocol</title><content type='html'>http://planet.time.net.my/TechnologyPark/evadeb/&lt;br /&gt;Eva apt 存档 (非官方)&lt;br /&gt;Eva 是一个可以与腾讯 QQ 互通的、基于 KDE 的自由软件即时通信工具。详情请参阅:&lt;br /&gt;http://sourceforge.net/projects/evaq&lt;br /&gt;&lt;br /&gt;本网站为 Eva 的 Debian apt 存档。目前只提供 Debian sid 包。&lt;br /&gt;&lt;br /&gt;使用方法:&lt;br /&gt;1. 将下面的行添加到您的 /etc/apt/sources.list 文件中:&lt;br /&gt;  deb http://planet.time.net.my/TechnologyPark/evadeb ./&lt;br /&gt;2. 运行: apt-get update&lt;br /&gt;3. 运行: apt-get install eva 或使用 aptitude 安装 "eva" 包&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116839553135450320?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116839553135450320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116839553135450320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116839553135450320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116839553135450320'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/new-im-tool-for-qq-protocol.html' title='new im tool for qq protocol'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116830425676519596</id><published>2007-01-09T08:41:00.000+08:00</published><updated>2007-02-09T12:04:10.007+08:00</updated><title type='text'>setup chinese input methon in en_US local</title><content type='html'>- fullfil the file as follow&lt;br /&gt;kk:/home/kk# cat /etc/locale.gen&lt;br /&gt;en_US.UTF-8 UTF-8&lt;br /&gt;zh_CN.UTF-8 UTF-8&lt;br /&gt;&lt;br /&gt;- use locale-gen command to create a new locale&lt;br /&gt;&lt;br /&gt;- install scim, scim-pinyin, imswitch.&lt;br /&gt;&lt;br /&gt;- copy the documentation from /etc/X11/xinit/xinput.d/scim to /etc/X11/Xsession.d/90im-switch&lt;br /&gt;don't forget use "export" in front of each line declare.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;in ubuntu's fcitx:&lt;br /&gt;&lt;blockquote&gt;sudo apt-get install im-switch&lt;/blockquote&gt;&lt;br /&gt;make sure the fcitx file in /etc/X11/xinit/xinput.d/, and the file have some declare, or even copy this declare into the /ect/X11/Xsession.d/90im-switch.&lt;br /&gt;http://forum.ubuntu.org.cn/viewtopic.php?t=33401&amp;amp;highlight=fcitx&lt;br /&gt;Force the IM modules can works in en locale.&lt;table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="genmed"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td class="code"&gt;"/usr/lib/gtk-2.0/2.4.0/immodules/im-xim.so"&lt;br /&gt;"xim" "X Input Method" "gtk20" "/usr/share/locale" "en:ko:ja:th:zh"&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116830425676519596?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116830425676519596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116830425676519596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116830425676519596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116830425676519596'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2007/01/setup-scim-in-debian-enutf8.html' title='setup chinese input methon in en_US local'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116237330194674238</id><published>2006-11-01T17:24:00.000+08:00</published><updated>2006-11-01T17:28:30.373+08:00</updated><title type='text'>firefox加速</title><content type='html'>firefox 加速具体方法如下：&lt;br /&gt;启动FireFox，在地址栏中输入“about:config”，页面中找出以下选项（如果没有就新建一个）： “nglayout.initialpaint.delay”（默认值为250，更改为0）；“network.http.pipelining”（默认值为false，更改为true）；“network.http.proxy.pipelining”（默认值为false，更改为true）； “network.http.pipelining.maxrequests”（默认值为4，更改为8）完成设置后保存退出。&lt;br /&gt;&lt;br /&gt;似乎还可以修改/usr/bin/firefox&lt;br /&gt;export MOZ_DISABLE_PANGO=1&lt;br /&gt;&lt;br /&gt;重新打开FireFox，这时候就会发现浏览网页的速度比修改之前要快多了。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116237330194674238?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116237330194674238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116237330194674238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116237330194674238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116237330194674238'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/11/firefox.html' title='firefox加速'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116128104793470518</id><published>2006-10-20T01:56:00.000+08:00</published><updated>2006-10-20T02:04:08.433+08:00</updated><title type='text'>virtual host in apache2</title><content type='html'>1, declare/unify all the virtual host with IP in /etc/hosts file or DNS.&lt;br /&gt;2, plus the content as follow in the /etc/apache2/sites-enabled/000-default:&lt;br /&gt;&lt;VirtualHost *&gt;&lt;br /&gt;DocumentRoot /tmp/test&lt;br /&gt;ServerName kk.org&lt;br /&gt;&lt;/VirtualHost&gt;&lt;br /&gt;# as least your must declare to parameter, the documentroot and servername.&lt;br /&gt;be mind that all the servername you want to display must be declare in hosts or DNS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116128104793470518?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116128104793470518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116128104793470518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116128104793470518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116128104793470518'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/10/virtual-host-in-apache2.html' title='virtual host in apache2'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116118004100759830</id><published>2006-10-18T21:51:00.000+08:00</published><updated>2006-10-18T22:00:44.113+08:00</updated><title type='text'>ftpd</title><content type='html'>edit the /etc/vsftpd as follow:&lt;br /&gt;local_enable=YES&lt;br /&gt;write_enable=YES&lt;br /&gt;chroot_local_user=YES&lt;br /&gt;then restart vsftpd, the local user is enable now.&lt;br /&gt;plus the follow inside the file mentioned upsite:&lt;br /&gt;user_config_dir=/etc/vsftpd/vsftpd_user_conf&lt;br /&gt;then we make the directory as clue&lt;br /&gt;mkdir -p /etc/vsftpd/vsftpd_user_conf , be mind that it must be a dir.&lt;br /&gt;then create the file and modify your user:&lt;br /&gt;echo XXX &gt; ftpuser&lt;br /&gt;local_root=PATH to directory就可以更改用户的home directory&lt;br /&gt;local_max_rate=XXXX就可以限制此用户的带宽.&lt;br /&gt;cmds_allowed=XXXXX, 此用户可以使用的指令&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116118004100759830?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116118004100759830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116118004100759830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116118004100759830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116118004100759830'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/10/ftpd.html' title='ftpd'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-116040967500032387</id><published>2006-10-09T23:51:00.000+08:00</published><updated>2006-10-10T01:32:33.266+08:00</updated><title type='text'>authentication for http</title><content type='html'>step 1: edit /etc/apache2/site-enable/000-default:&lt;br /&gt;        DocumentRoot /var/www/&lt;br /&gt;        &lt;Directory /&gt;&lt;br /&gt;                Options FollowSymLinks&lt;br /&gt;                AllowOverride authconfig &lt;br /&gt;#none for default, authconfig make authen enable&lt;br /&gt;                authtype basic&lt;br /&gt;                authname 'testing'&lt;br /&gt;                authuserfile /etc/apache2/password&lt;br /&gt;#mark the password file location&lt;br /&gt;                require user htpass&lt;br /&gt;#"Require valid-user #all valid user" require valid user is default, &lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;step 2: create a password file "password" with a user "htpass":&lt;br /&gt;htpasswd -c /etc/apache2/password htpass&lt;br /&gt;&lt;br /&gt;more apache setting in :&lt;br /&gt;http://debian.ha.cn/htmldata/5/2005_10/article_176_1.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-116040967500032387?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/116040967500032387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=116040967500032387' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116040967500032387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/116040967500032387'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/10/authentication-for-http.html' title='authentication for http'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115867943521057022</id><published>2006-09-19T23:17:00.000+08:00</published><updated>2006-09-20T19:59:09.016+08:00</updated><title type='text'>pure-ftpd-mysql setting</title><content type='html'>http://www.linuxsky.net/html/200604/2948.html&lt;br /&gt;首先必须确定本地用户能登录，否则的话&lt;br /&gt;#cp /usr/sbin/pure-ftpd-mysql /usr/sbin/pure-ftpd 。&lt;br /&gt;使用mysql的root帐号比较方便，所以是&lt;br /&gt;grant all privileges on FTP.* to localhost identified by '123456'&lt;br /&gt;最后PureFTP User Management能使用的话而虚拟用户不能使用的话就是pureftpd的设置问题了，注意ftp根目录和ftp用户的所属关系。&lt;br /&gt;必须在系统里面建立一个名为ftp的用户，当然也要把/etc/pure-ftpd/conf/NoAnonymous 改为no。&lt;br /&gt;我是这个做的：useradd ftp -g ftpgroup -d /yourftpdir -s /etc&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115867943521057022?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115867943521057022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115867943521057022' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115867943521057022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115867943521057022'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/pure-ftpd-mysql-setting.html' title='pure-ftpd-mysql setting'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115761766371421790</id><published>2006-09-07T16:25:00.000+08:00</published><updated>2006-10-02T18:00:44.823+08:00</updated><title type='text'>remind</title><content type='html'>在哪里能找到免费的域名&lt;br /&gt;forum.prayaya.com中这个forum代表什么，怎么能实现&lt;br /&gt;vsftpd的3种登陆方式：&lt;br /&gt;http://www.linuxsir.org/bbs/showthread.php?t=270044&lt;br /&gt;http://linux.chinaunix.net/docs/2006-08-29/2589.shtml&lt;br /&gt;正则表达式 Regular Expression&lt;br /&gt;ssh对于内网的应用&lt;br /&gt;http://linuxsir.org/bbs/showthread.php?t=37295&lt;br /&gt;http://linuxsir.org/bbs/showthread.php?t=274449&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115761766371421790?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115761766371421790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115761766371421790' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115761766371421790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115761766371421790'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/remind.html' title='remind'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115759520714466067</id><published>2006-09-07T10:12:00.000+08:00</published><updated>2006-09-07T10:13:27.583+08:00</updated><title type='text'>make cloop tool</title><content type='html'>#!/bin/bash&lt;br /&gt;#引导程序&lt;br /&gt;BOOTLOADER=""&lt;br /&gt;#制作ISO&lt;br /&gt;MKBOOTISO=""&lt;br /&gt;#制作CLOOP文件&lt;br /&gt;MKCLOOP=""&lt;br /&gt;#源&lt;br /&gt;SOURCE=""&lt;br /&gt;#是否使用日期结尾的文件名？&lt;br /&gt;USEDATE=""&lt;br /&gt;#程序名&lt;br /&gt;PROGRAMNAME=$0&lt;br /&gt;#压缩算法&lt;br /&gt;COMPRESS="9"&lt;br /&gt;#清空临时文件&lt;br /&gt;FLUSH=""&lt;br /&gt;#帮助&lt;br /&gt;usage()&lt;br /&gt;{&lt;br /&gt;echo "使用方法:$PROGRAMNAME [选项]&lt;br /&gt;  选项：&lt;br /&gt;  -h 本页&lt;br /&gt;  -7 使用7zip压缩，压缩率比默认的gzip略高，但所花时间会多很多&lt;br /&gt;  -b 指定引导程序(小写grub或isolinux，缺省为isolinux)&lt;br /&gt;  -c 目标cloop文件名&lt;br /&gt;  -d 在目标ISO文件名加上日期、时间&lt;br /&gt;  -f 清除制作时的一些临时文件&lt;br /&gt;  -i 目标ISO文件名&lt;br /&gt;  -s 源目录/cloop文件名"&lt;br /&gt;  return 1&lt;br /&gt;}&lt;br /&gt;while [ -n "$1" ]; do&lt;br /&gt;case $1 in&lt;br /&gt; -h) usage;shift 1;; # 帮助&lt;br /&gt; -b) shift 1;BOOTLOADER=$1;shift 1;;&lt;br /&gt; -i) shift 1;MKBOOTISO=$1;shift 1;;&lt;br /&gt; -c) shift 1;MKCLOOP=$1;shift 1;;&lt;br /&gt; -s) shift 1;SOURCE=$1;shift 1;;&lt;br /&gt; -d) shift 1;USEDATE="yes";;&lt;br /&gt; -7) shift 1;COMPRESS="-1";shift 1;;&lt;br /&gt; -f) shift 1;FLUSH="yes";;&lt;br /&gt; --) shift;break;; # 已经没有选项&lt;br /&gt; -*) echo "错误： 没有$1选项. $0 -h查看帮助";;&lt;br /&gt; *) break;;&lt;br /&gt;esac&lt;br /&gt;done &lt;br /&gt;make_cloop()&lt;br /&gt;{&lt;br /&gt;TYPE=$(file $SOURCE |cut -f 2 -d " ")&lt;br /&gt;if [ "$TYPE" == "ISO" ];then&lt;br /&gt; /usr/bin/create_compressed_fs -B 65536 -L $COMPRESS -r $SOURCE $MKCLOOP&lt;br /&gt; return 0&lt;br /&gt;else&lt;br /&gt; mkisofs -R -U -V "inlsd.org filesystem" -publisher "INLSD www.inlsd.org" -hide-rr-moved -cache-inodes -no-bak -pad $SOURCE |/usr/bin/create_compressed_fs -L $COMPRESS -B 65536 -r - $MKCLOOP&lt;br /&gt; return 0&lt;br /&gt;fi&lt;br /&gt;return 1&lt;br /&gt;}&lt;br /&gt;make_boot_iso()&lt;br /&gt;{&lt;br /&gt;if [ -z "$BOOTLOADER" ] -o [ "$BOOTLOADER" == "isolinux" ];then&lt;br /&gt; mkisofs -pad -l -r -J -v -V "INLSD SYSTEM" -no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -hide-rr-moved -o $MKBOOTISO $SOURCE&lt;br /&gt; return 0&lt;br /&gt;elif [ "$BOOTLOADER" == "grub" ];then&lt;br /&gt; mkisofs -pad -l -r -J -v -V "INLSD SYSTEM" -no-emul-boot -boot-load-size 4 -boot-info-table -b boot/grub/stage2_eltorito -hide-rr-moved -o $MKBOOTISO $SOURCE&lt;br /&gt; return 0&lt;br /&gt;else&lt;br /&gt; echo "错误！-b参数不是grub或isolinux！"&lt;br /&gt;fi&lt;br /&gt;return 1&lt;br /&gt;}&lt;br /&gt;if [ ! -x /usr/bin/create_compressed_fs ];then&lt;br /&gt; echo "错误，没有cloop工具。"&lt;br /&gt; exit 1&lt;br /&gt;fi&lt;br /&gt;if [ ! -x /usr/bin/mkisofs ];then&lt;br /&gt; echo "错误，没有mkisofs工具。"&lt;br /&gt; exit 1&lt;br /&gt;fi&lt;br /&gt;if [ -n "$USEDATE" ];then&lt;br /&gt; MKBOOTISO=$(echo $MKBOOTISO|sed 's/\.[iI][Ss][Oo]$//g')$(date +%Y%m%d-%H%M%S).iso&lt;br /&gt;fi&lt;br /&gt;if [ -n "$MKBOOTISO" -a -n "$MKCLOOP" ];then&lt;br /&gt; echo "错误！-i参数不能与-c或-d参数同时使用！"&lt;br /&gt; exit 1&lt;br /&gt;fi&lt;br /&gt;if [ -n "$FLUSH" -a -n "$MKCLOOP" ];then&lt;br /&gt; rm -rf  $SOURCE/.??* $SOURCE/home/* $SOURCE/home/.??* $SOURCE/root/* $SOURCE/root/.??* $SOURCE/etc/sysconfig/*  $SOURCE/var/cache/apt/*cache.bin $SOURCE/var/tmp/* $SOURCE/var/tmp/.??* $SOURCE/tmp/* $SOURCE/tmp/.??*  $SOURCE/var/lib/apt/lists/debian.cn99.com*&lt;br /&gt; rm  $SOURCE/mnt/*&lt;br /&gt; rmdir $SOURCE/media/*&lt;br /&gt; touch $SOURCE/etc/sysconfig/xsession-commands&lt;br /&gt;fi&lt;br /&gt;if [ -n "$MKBOOTISO" ];then&lt;br /&gt; make_boot_iso&lt;br /&gt;elif [ -n "$MKCLOOP" ];then&lt;br /&gt; make_cloop&lt;br /&gt;else&lt;br /&gt; usage&lt;br /&gt;fi&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115759520714466067?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115759520714466067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115759520714466067' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115759520714466067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115759520714466067'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/make-cloop-tool.html' title='make cloop tool'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755932862698328</id><published>2006-09-07T00:14:00.000+08:00</published><updated>2006-09-07T00:15:28.843+08:00</updated><title type='text'>小李的blog</title><content type='html'>http://huanff.blog.sohu.com/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755932862698328?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755932862698328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755932862698328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755932862698328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755932862698328'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/blog.html' title='小李的blog'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755860885504899</id><published>2006-09-07T00:01:00.000+08:00</published><updated>2006-09-07T00:03:30.936+08:00</updated><title type='text'>the minimun required for X launch</title><content type='html'>xserver-xorg, xbase-clients, xfonts-base&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755860885504899?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755860885504899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755860885504899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755860885504899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755860885504899'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/minimun-required-for-x-launch.html' title='the minimun required for X launch'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755847260752725</id><published>2006-09-06T23:59:00.000+08:00</published><updated>2006-09-07T00:01:17.636+08:00</updated><title type='text'>shell for debmirror</title><content type='html'>#cat /mnt/hdd11/debmirror.etch.sh&lt;br /&gt;#debmirror debmirror.sarge/ -host 221.6.69.11 -arch i386 --progress --dist sarge --ignore-release-gpg --nosource --exclude=potato&lt;br /&gt;#debmirror debmirror.security/ -host security.debian.org -arch i386 --progress -r /debian-security --dist sarge/updates --section=main,contrib,non-free --ignore-release-gpg --nosource --exclude=potato&lt;br /&gt;#debmirror debmirror.etch/ -host debian.cn99.com -e http -arch i386 --progress --dist etch --ignore-release-gpg --nosource --exclude=potato&lt;br /&gt;debmirror debmirror.etch/ -host debian.inlsd.com -e http -arch i386 --progress --dist etch --ignore-release-gpg --nosource --exclude=potato&lt;br /&gt;#debmirror debmirror.sid/ -host 221.6.69.11 -arch i386 --progress --dist sid --ignore-release-gpg --nosource --exclude=potato&lt;br /&gt;#halt&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755847260752725?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755847260752725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755847260752725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755847260752725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755847260752725'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/shell-for-debmirror.html' title='shell for debmirror'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755830033145822</id><published>2006-09-06T23:56:00.000+08:00</published><updated>2006-09-06T23:58:20.473+08:00</updated><title type='text'>mplayer for debian</title><content type='html'>echo "deb http://www.debian-multimedia.org etch main" &gt;&gt; /etc/apt/source.list&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755830033145822?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755830033145822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755830033145822' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755830033145822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755830033145822'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/mplayer-for-debian.html' title='mplayer for debian'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755817413216701</id><published>2006-09-06T23:55:00.000+08:00</published><updated>2006-09-06T23:56:23.206+08:00</updated><title type='text'>VOA radio</title><content type='html'>mplayer -cache 100 rtsp://a1702.l211048984.c2110.g.lr.akamaistream.net:554/live/D/1702/2110/v0001/reflector:48984&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755817413216701?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755817413216701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755817413216701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755817413216701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755817413216701'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/voa-radio.html' title='VOA radio'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755802279858419</id><published>2006-09-06T23:51:00.000+08:00</published><updated>2006-09-06T23:53:44.246+08:00</updated><title type='text'>Knoppix's file systme cloop</title><content type='html'>mount -o loop xxx.iso /cdrom&lt;br /&gt;extract_compressed_fs /cdrom/KNOPPIX/KNOPPIX &gt; cloop.iso&lt;br /&gt;  umount /cdrom&lt;br /&gt;  mount -o loop cloop.iso /cdrom&lt;br /&gt;cp -av /cdrom/* /xxx&lt;br /&gt;用這個方法解開，不要安裝&lt;br /&gt;解開後chroot方法安裝軟件&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755802279858419?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755802279858419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755802279858419' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755802279858419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755802279858419'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/knoppixs-file-systme-cloop.html' title='Knoppix&apos;s file systme cloop'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755787334442249</id><published>2006-09-06T23:49:00.000+08:00</published><updated>2006-09-06T23:51:13.496+08:00</updated><title type='text'>disk's R&amp;R</title><content type='html'>backup:&lt;br /&gt;dd if=/dev/hda of= backup-hda.mbr count=1 bs=512&lt;br /&gt;sfdisk -d /dev/hda &gt; backup-hda.sf&lt;br /&gt;&lt;br /&gt;restore&lt;br /&gt;dd if=backup-hda.mbr of=/dev/hda&lt;br /&gt;sfdisk /dev/hda &lt; backup-hda.sf&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755787334442249?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755787334442249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755787334442249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755787334442249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755787334442249'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/disks-rr.html' title='disk&apos;s R&amp;R'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755773361406356</id><published>2006-09-06T23:47:00.000+08:00</published><updated>2006-09-06T23:48:53.820+08:00</updated><title type='text'>qemu boot an ISO</title><content type='html'>qemu -cdrom prayaya-linux-en-20060825.iso -hda /dev/sda -boot d&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755773361406356?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755773361406356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755773361406356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755773361406356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755773361406356'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/qemu-boot-iso.html' title='qemu boot an ISO'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755722806744153</id><published>2006-09-06T23:39:00.000+08:00</published><updated>2006-09-06T23:40:28.246+08:00</updated><title type='text'>xmms' font setting for zh_CN</title><content type='html'>-*-*-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0,*-r-*&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755722806744153?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755722806744153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755722806744153' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755722806744153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755722806744153'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/xmms-font-setting-for-zhcn.html' title='xmms&apos; font setting for zh_CN'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115755710921513341</id><published>2006-09-06T23:36:00.000+08:00</published><updated>2006-09-06T23:45:20.816+08:00</updated><title type='text'>DNS 3322.org＇s auto config</title><content type='html'>lynx -mime_header -auth=username:password "http://www.3322.org/dyndns/update?system=dyndns&amp;hostname=myhost.3322.org"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115755710921513341?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115755710921513341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115755710921513341' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755710921513341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115755710921513341'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/dns-3322orgs-auto-config.html' title='DNS 3322.org＇s auto config'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115751176807444305</id><published>2006-09-06T11:02:00.000+08:00</published><updated>2006-09-06T11:02:48.370+08:00</updated><title type='text'>dhcpd.conf</title><content type='html'>option domain-name-servers 192.168.1.22;&lt;br /&gt;option subnet-mask 255.255.255.0;&lt;br /&gt;default-lease-time 600;&lt;br /&gt;max-lease-time 7200;&lt;br /&gt;subnet 192.168.1.0 netmask 255.255.255.0 {&lt;br /&gt;range 192.168.1.30 192.168.1.100;&lt;br /&gt;option broadcast-address 192.168.1.255;&lt;br /&gt;option routers 192.168.1.1;&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115751176807444305?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115751176807444305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115751176807444305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115751176807444305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115751176807444305'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/dhcpdconf.html' title='dhcpd.conf'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20554462.post-115750938656658030</id><published>2006-09-06T10:21:00.000+08:00</published><updated>2006-09-06T10:23:06.633+08:00</updated><title type='text'>Speeding up work at Linux command line part # 1</title><content type='html'>http://www.cyberciti.biz/nixcraft/vivek/blogger/2005/08/speeding-up-work-at-linux-command-line.html&lt;br /&gt;&lt;br /&gt;Working at shell prompt is an essential task for any Linux system administration. However many newcomers find it difficult to work at bash prompt. Here are some tricks to speed up your work. &lt;br /&gt;&lt;br /&gt;(A) Shortcut keys for command editing:&lt;br /&gt;CTRL+L : Clear the screen &lt;br /&gt;&lt;br /&gt;CTRL+R : To search for a command in command history. For example yesterday or few hourse back you typed 'a very very long command' and you need same command again. Then hit CTRL+R and type first few letters of command.&lt;br /&gt;&lt;br /&gt;CTRL+C : Cancel command &lt;br /&gt;&lt;br /&gt;CTRL+Z : Suspend command &lt;br /&gt;&lt;br /&gt;CTRL+T : transpose characters. For example by misspelled command date:&lt;br /&gt;＄ daet&lt;br /&gt;Sure you can rub the last two character and retype it again, but wait just hist CTRL+T and you are done:&lt;br /&gt;＄ daet [CTRL+T]&lt;br /&gt;Result into character transpose:&lt;br /&gt;＄ date&lt;br /&gt;&lt;br /&gt;ALT+T OR ESC+T: transpose words. For example you typed:&lt;br /&gt;＄ filename rm&lt;br /&gt;To correct it just hit ALT+T&lt;br /&gt;＄ filename rm [ALT+T]&lt;br /&gt;And you have correct command to remove a file.&lt;br /&gt;＄ rm filename &lt;br /&gt;&lt;br /&gt;CTRL+U : Deletes entire line&lt;br /&gt;&lt;br /&gt;CTRL+K : Deletes to end of line from current cursor position &lt;br /&gt;&lt;br /&gt;HOME OR CTRL+A : Moves cursor to beginning of line &lt;br /&gt;&lt;br /&gt;END OR CTRL+E : Moves cursor to end of line &lt;br /&gt;&lt;br /&gt;(B)Recall last argument from previous command – to save time&lt;br /&gt;ALT+. (hold down ALT key and press period/dot)&lt;br /&gt;For example first you typed the mkdir command as follows:&lt;br /&gt;＄ mkdir -p /tmp/demo/software/qtapp&lt;br /&gt;Now you would like change directory to /tmp/demo/software/qtapp, then type cd and press ALT+.:&lt;br /&gt;＄ cd [PRESS alt+.]&lt;br /&gt;&lt;br /&gt;(C) Command completion &lt;br /&gt;Most of the Linux admin uses TAB key to complete command names and files names. So let us say you would like to mount something then:&lt;br /&gt;i) Type word mo:&lt;br /&gt;＄ mo&lt;br /&gt;ii) Hit TAB key to complete word &lt;br /&gt;＄ mo [TAB]&lt;br /&gt;iii) And end result should be:&lt;br /&gt;＄ mount &lt;br /&gt;&lt;br /&gt;(D) List the possible completions&lt;br /&gt;BASH also supports the possible completions of commands or text (file). For example you would like to list all the possible command starts with ls command:&lt;br /&gt;＄ ls [ESC]&lt;br /&gt;Will display following text (above the current command line) &lt;br /&gt;&lt;br /&gt;ls lsmod lsmod.modutils lspci lsusblsattr lsmod.Lmodutils lsof&lt;br /&gt;&lt;br /&gt;Next time I will discuss more about advanced command line completions and other cool features. &lt;br /&gt;*** If you enjoyed this article, grab our Feed OR Subscribe to the nixCraft email newsletter OR use Technorati to track all updates. ***&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20554462-115750938656658030?l=kingkongmok.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kingkongmok.blogspot.com/feeds/115750938656658030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20554462&amp;postID=115750938656658030' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115750938656658030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20554462/posts/default/115750938656658030'/><link rel='alternate' type='text/html' href='http://kingkongmok.blogspot.com/2006/09/speeding-up-work-at-linux-command-line.html' title='Speeding up work at Linux command line part # 1'/><author><name>kingkongmok</name><uri>http://www.blogger.com/profile/04086110112694796351</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
