Add New Notes
195
Zim/Utils/Boot_with_GRUB.txt
Normal file
@@ -0,0 +1,195 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-11-03T14:20:14+08:00
|
||||
|
||||
====== Boot with GRUB ======
|
||||
Created Thursday 03 November 2011
|
||||
http://www.linuxjournal.com/article/4622
|
||||
|
||||
May 2001
|
||||
Apr 30, 2001 By Wayne Marshall
|
||||
|
||||
//Especially useful for multiboot, partitioned systems, GRUB offers flexibility and convenience for startup.//
|
||||
|
||||
**GRUB:** it's neither larva, fast food nor the loveliest of acronyms in the GNU herd of free software. Rather, GRUB is the// GNU GRand Unified Bootloader.// And, it is truly the greatest loader for booting Linux and practically any other OS—open source or otherwise—you may have scattered on your platters.
|
||||
|
||||
GRUB is independent of any particular operating system and may be thought of as a tiny, function-specific OS. The purpose of the GRUB kernel is to__ recognize filesystems and load boot images__, and it provides both menu-driven and command-line interfaces to perform these functions. The command-line interface in particular is quite flexible and powerful, with command history and completion features familiar to users of the bash shell.
|
||||
|
||||
GRUB is in its element with the multiboot, multidisk systems typical of Linux and open-source adventurers who may simultaneously test or track several Linux distributions, the BSDs, GNU/Hurd, BeOS and perhaps that vestigial partition for Mr. Bill. Even if you stick with LILO as your system's primary boot loader, it's smart to keep a GRUB boot floppy handy as the best and fastest way to get your system back if you otherwise cream your master boot record (MBR). If you have done any number of multiboot installations, you know exactly what I'm talking about. Should you need any more reasons for considering GRUB, check out the sidebar, “Why GRUB”. Let's get started!
|
||||
Installation
|
||||
|
||||
Installation of GRUB is a **two-step **process. The first step is to install or build GRUB in a host OS environment, and for this we will, of course, use Linux. The second step is to install and configure GRUB as the boot loader for your system.
|
||||
|
||||
The first step is the usual: download the source archive, untar it, configure and make install. Assuming you have found a source mirror (see www.gnu.org/software/grub/grub.html) and downloaded the source distribution into a suitable working directory, continue with:
|
||||
|
||||
tar -xzvf grub-0.5.96.1.tar.gz
|
||||
cd grub-0.5.96.1
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
This should create the executables: **grub, grub-install and mbchk**; install support files in /usr/local/share/grub/i386-pc/, and install the GNU information manual and man pages.
|
||||
|
||||
For the second step of installation, we will first build and work with a GRUB boot floppy. This way we can use GRUB to learn about its features while testing various configurations for our particular system. After getting comfortable with the GRUB setup on floppy, we will then install it onto the** MBR** of the system's** first** hard disk. Even if you decide not to install GRUB on your hard disk right away, no harm done: you will now have your own GRUB boot floppy available to rescue systems with trashed boot loaders.
|
||||
|
||||
===== Preparing a GRUB floppy =====
|
||||
|
||||
GRUB recognizes a number of different filesytem types, including Linux ext2fs, Reiser, MINIX, BSD's ffs, as well as FAT, so it is possible to make a GRUB boot floppy with// any //of these filesystems. We will stick to FAT for this example, however, because it is the lowest common denominator, and most OSes have tools for mounting and reading/writing files on FAT floppies. That way, we will always be able to get to its menu configuration file if we need to.
|
||||
|
||||
Scrounge around in your junk drawer for some unused floppy (a new one would be even better), and give it a fresh format and FAT filesystem:
|
||||
|
||||
fdformat /dev/fd0
|
||||
mkfs -t msdos /dev/fd0
|
||||
|
||||
We are going to put some files on this disk, so go ahead and mount to your usual floppy mount point (here I use /floppy):
|
||||
|
||||
mount -t msdos /dev/fd0 /floppy
|
||||
|
||||
Now install the directories and files GRUB will need:
|
||||
|
||||
mkdir -p /floppy/boot/grub
|
||||
cp /usr/local/share/grub/i386-pc/stage* /floppy/**boot/grub**
|
||||
|
||||
The floppy can then be unmounted, umount /floppy, but leave it in the drive. The GRUB floppy is prepared and ready for the final installation, which is to install the GRUB boot loader in the **MBR** of the floppy itself. For that, we will use the grub executable we have built with our Linux installation. Start the executable at the Linux command prompt: grub.
|
||||
|
||||
This brings up an emulator of GRUB's command shell environment, which looks like Figure 1. We will discuss the features of this shell in more detail a little further on. For now, enter the following series of commands at the grub prompt:
|
||||
|
||||
grub> root (fd0)
|
||||
grub> setup (fd0)
|
||||
grub> quit
|
||||
|
||||
Figure 1. GRUB in command-line mode. Note the on-line help (here the GRUB emulator is running under Linux in an xterm window).
|
||||
|
||||
And that's it! This sequence of commands completes the installation of GRUB on the floppy disk. It is now bootable and will allow us to boot any other OS on our system.
|
||||
|
||||
===== Demonstrating GRUB =====
|
||||
|
||||
To see how GRUB may be used to boot a multitude of different operating systems, consider this example setup:
|
||||
|
||||
First Hard Disk (SCSI, Linux /dev/sda): 1st primary partition: Win982nd primary partition: Linux-Slackware3rd primary partition: Linux-Debian4th primary partition: Linux SwapSecond Hard Disk (SCSI, Linux /dev/sdb)1st primary partition: FreeBSD2nd primary partition: OpenBSD3rd primary partition: BeOS
|
||||
|
||||
Note that although GRUB and Linux are capable of dealing with installations in extended partitions, here we show a preference for using primary partitions whenever possible. Filesystems in primary partitions are often mountable by other operating systems, whereas cross-OS mounting filesystems in extended partitions is often not supported.
|
||||
|
||||
This system has two hard disks with six different operating systems using seven partitions. As you probably know, each OS has its own nomenclature for naming devices and partitions. For example, the Slackware installation would be known to Linux as /dev/sda2 (with swap on /dev/sda4), while FreeBSD would recognize its filesystem on /dev/da1s1a. Alternatively, if the system were configured with IDE hard disks, Slackware would be on /dev/hda2, and FreeBSD would refer to its root directory on /dev/ad1s1a. You get large helpings of this alphabet soup whenever maintaining any multiboot setup.
|
||||
|
||||
Since GRUB also needs to be capable of loading any of these systems, it has its own OS-neutral naming conventions for referring to devices. Hard disks are all hd, floppy disks are fd, device numbering starts from zero, partition numbering starts from zero and complete device names are enclosed in parentheses.
|
||||
|
||||
With these naming rules, the floppy disk is (fd0), the Win98 partition is (hd0,0), and GRUB recognizes the Slackware and Debian partitions respectively as (hd0,1) for slackware and (hd0,2) for debian.
|
||||
|
||||
The BSDs further subdivide their own partitions (or “slices” in BSD terms), and GRUB would refer to the root mount for the FreeBSD system on (hd1,0,a).
|
||||
|
||||
Okay, ready to give GRUB a taste? Slide the GRUB floppy in the drive and reboot your system (with your system's BIOS configured to boot from A: drive). You should see GRUB's terse boot messages and then find yourself in the GRUB command-line environment as shown in Figure 1.
|
||||
|
||||
To start, let's boot Slackware. Enter the following commands at the grub prompt:
|
||||
|
||||
grub> root (hd0,1)
|
||||
grub> kernel /vmlinuz root=/dev/sda2 ro vga=791
|
||||
grub> boot
|
||||
|
||||
Badda-bing, badda-boom, that postage-stamp-sized Tux appears in the upper-left corner of your screen (yes, Slackware is configured to use the framebuffer device), and Linux bootstraps its jolly way into glorious being.
|
||||
|
||||
Another example. Reboot the system again with the GRUB floppy, and enter the following commands at the grub prompt:
|
||||
|
||||
grub> rootnoverify (hd0,0)
|
||||
grub> makeactive
|
||||
grub> chainloader +1
|
||||
grub> boot
|
||||
|
||||
Now your screen turns into a vague blue cloud, and you think you have made some horrible mistake. Then you realize it's only Windows and you remind yourself to expunge this partition one day soon.
|
||||
|
||||
Let's take a closer look at these examples. In the Slackware boot, we first used the GRUB root command to specify the device for GRUB to access. If the device has a filesystem recognized by GRUB (that is, one of ext2fs, reiser, ffs, etc.), it attempts to mount it and get its partition information, then reports its success following the command. Thus, you would see the following command/response dialog on your screen:
|
||||
|
||||
grub> root (hd0,1)
|
||||
Filesystem type is ext2fs, partition type 0x83
|
||||
|
||||
Next, we used the GRUB kernel command to specify the boot image for GRUB to load. The argument to the kernel command is the filename of the boot image relative to the device specified by the root command above. The kernel image file can also be specified in explicit (device)/filename terms as follows:
|
||||
|
||||
grub> kernel (hd0,1)/vmlinuz
|
||||
|
||||
The kernel command gives you great flexibility for specifying the boot image you wish to load. For example, if we saved a previous version of a kernel to the file /vmlinuz.old, we could specify it with this command (which shows GRUB's response):
|
||||
|
||||
grub> kernel /vmlinuz.old root=/dev/sda2 ro vga=ask
|
||||
[Linux-bzImage, setup=0xe00, size=0xfad30]
|
||||
|
||||
The arguments following the name of the boot image are passed to the target kernel and aren't related to GRUB. For Linux, these kernel arguments are pretty much what you would specify them to be in lilo.conf. In our example, we tell the kernel what device to mount for the root partition (root=/dev/sda2 ro), using the device nomenclature expected by Linux. Note here that we also use the ro flag to mount the root filesystem read-only initially while it performs its filesystem check. The other kernel argument in our example simply demonstrates setting another kernel variable (vga=791) to use a particular vga mode for the framebuffer display.
|
||||
|
||||
Finally, the last command is grub> boot. The kernel image specified is now loaded and sent rolling down the royal road to bootdom.
|
||||
|
||||
The second example, using Win98, demonstrates the use of GRUB's chain-loading mechanism. This method of booting loads the target OS's own boot-chain-loader rather than a kernel image of the OS. In this instance, we specified:
|
||||
|
||||
grub> rootnoverify (hd0,0)
|
||||
grub> chainloader +1
|
||||
|
||||
First, the rootnoverify command is for OS filesystems not specifically recognized by GRUB, so that GRUB will not try to mount the partition. Next, the chainloader command will use the first sector of the partition of device (hd0,0) and attempt to boot whatever it finds there. This is a common means of booting OSes that install their own boot loaders in the first sector of the partition where they are installed (this is sometimes called the partition boot sector or PBR).
|
||||
|
||||
Finally, the makeactive command sets the active flag in the partition table for the device specified by the root command, as some operating systems, like Win98, require.
|
||||
|
||||
The GRUB command line is easy and fun, and you should boot the different OSes on your system a few times to get the hang of it. While you are testing, be sure to keep any notes specific to getting your particular kernels successfully loaded. This information will be useful later when you configure the menu system of GRUB to perform these command-line steps automatically.
|
||||
|
||||
But before we leave the command line, here are a few more GRUB commands to look at.
|
||||
|
||||
The help command will display a list of the 40 or so commands available in GRUB. Typing the name a particular command after help will produce on-line help for that particular command. So grub> help kernel will tell you all about using the kernel command.
|
||||
|
||||
The cat command can be used to view the contents of a file. For example, grub> cat (hd0,2)/etc/fstab will show the contents of the /etc/fstab file in the Debian installation. This is a very handy way of pulling out system configuration information if your normal boot loader gets whacked. Note also as you are using the GRUB command line that, like bash, up and down arrows will scroll through command history, and a tab will complete the name of a GRUB command or filename.
|
||||
|
||||
Finally, you can call up a specific menu interface with the configfile command as in:
|
||||
|
||||
grub> configfile (fd0)/boot/grub/menu.lst
|
||||
|
||||
This will switch GRUB into its menu mode with an interface defined by the file, menu.lst. We haven't created that file yet, but—look out, segue coming!—that's exactly what we will do next.
|
||||
|
||||
|
||||
===== Menu Configuration =====
|
||||
|
||||
Using the GRUB command line is cool, but after a few thousand system starts, you will probably get a little tired of entering the same commands at the GRUB prompt and long for something a little more automated. Good news from the GRUB gang: you get a fully configurable menu interface at no extra charge! The GRUB boot menu gives you point-and-shoot boot selection, unattended default boot after a configurable timeout, any number of fallback boots if previous boots fail, toggle between command-line and menu modes, and interactive editing of menu selections and password protection. These features give GRUB an ease of use to match its tremendous functionality.
|
||||
|
||||
When GRUB boots, it automatically looks for the /boot/grub/menu.lst file on its boot device (the last three letters are “ELL ess tee” and not “one ess tee”). If the file is found, GRUB automatically enters its menu mode and presents the user with a stunning interface, as shown in Figure 2.
|
||||
|
||||
Figure 2. GRUB's Boot Menu Interface
|
||||
|
||||
Listing 1 [found at LJ's web site] shows the configuration file responsible for this demonstration menu. As you can see, it is a simple text file typical of many UNIX configuration files, where lines starting with hashes (#) and blank lines are ignored.
|
||||
|
||||
The first set of commands sets general configuration variables. The timeout command sets the time in seconds to wait for the user to make a selection before proceeding automatically to the default boot. The default command sets which of the following boot stanzas GRUB should attempt to boot automatically. Boot stanzas are numbered implicitly, starting from zero, according to their order of appearance in the configuration file. This order is also how they will be listed in the menu.
|
||||
|
||||
The fallback command specifies which of the boot stanzas to load if the default should fail. It is possible to set more than one fallback, as is shown in the example.
|
||||
|
||||
The color command lets you breathe a bit of life into the text-mode menu screen. The syntax for the color command is
|
||||
|
||||
color foreground/background [ hilite-fg/hilite-bg ]
|
||||
|
||||
where each of the foreground/background colors is specified with a name from the set of black, blue, green, cyan, red, magenta, brown and light-gray; dark-gray, light-blue, light-green, light-cyan, light-cyan, light-red, light-magenta, yellow and white. Among these colors, only the first eight are used for the background. The optional highlight color pair, if specified, will be used to show the current menu selection. When not specified, GRUB will use the inverse of the normal colors.
|
||||
|
||||
The rest of the configuration file consists of the boot stanzas for our demonstration system. The title command marks the beginning of a new boot stanza, and its argument is the label that will be displayed for its entry in the menu, from the first non-white-space character to the end of the line. The remaining commands in each stanza are identical to those used when working from the GRUB command line. The exception here is that we no longer need to give a boot command; GRUB does this job without asking.
|
||||
|
||||
This example configuration gives only a sample of the many flexible uses of the GRUB boot loader. Besides multiple OSes, you can use GRUB to set up menu selections for test kernels, rescue kernels, different kernel options and so on.
|
||||
|
||||
All in all, the GRUB configuration file will be very similar to your /etc/lilo.conf. And after working with the GRUB command line and these examples, it should be a simple matter of firing up your favorite text editor and creating a menu configuration file suitable for your own system and preferences. Don't worry if it's not perfect the first time; you will see that you can make changes interactively, and the GRUB command line is always available as a fallback.
|
||||
|
||||
Once you've got your configuration file, mount your GRUB floppy again, and copy the file (say it has been saved as mygrub.conf) into the magic location:
|
||||
|
||||
cp mygrub.conf /floppy/boot/grub/menu.lst
|
||||
|
||||
Now when you boot with your GRUB floppy—presto!—you will be greeted with a lovely boot menu like the one in Figure 2. If you like, just stare at it for the few seconds it needs to count down from the timeout setting, and then it will automatically boot into your default OS. Or, use the arrow keys to highlight the OS you want to load and press return. Or, type c to go to the now-familiar GRUB command prompt. From the command prompt, press ESC to go back to the boot menu again.
|
||||
|
||||
It is also possible to edit the entries displayed in the menu. Typing e will open a simple vi-like editor interface for the highlighted entry. This allows you to adjust or add any settings to the configuration before booting. Any changes made here will then remain in effect for the duration of the GRUB session. To make permanent changes, you will later need to edit the configuration file on the boot disk, saving the changes with your text editor.
|
||||
|
||||
Play with your GRUB floppy configuration until you have it set up the way you like. After just a few system boots, you'll be slinging through GRUB like hashbrowns in a diner.
|
||||
|
||||
===== Conclusions =====
|
||||
|
||||
As is typical of GNU software, GRUB is rich with capabilities beyond what are described here. Some of these include:
|
||||
|
||||
Remapping disks and partition hiding, so you can even run multiple versions of DOS/Windows, on other than the first hard disk.
|
||||
|
||||
Network booting with BOOTP and DHCP protocols, to support multiboot schemes across a network and diskless operation.
|
||||
|
||||
Keyboard remapping, disk geometry access, memory reading, I/O port and processor probes, password protection, decompression support, etc.
|
||||
|
||||
See the GNU information manual for more information on these topics. GRUB is under active development, and even more features are planned for future releases.
|
||||
|
||||
In this brave GNU world, with vast acreage of cheap hard disk and a glut of great free OSes available, you really need a flexible and user-friendly boot loader to manage them all. Grab GRUB and give it a go.
|
||||
|
||||
Why GRUB?
|
||||
|
||||
Wayne Marshall (guinix@yahoo.com) is a UNIX programmer and technical consultant currently living in Guinea, West Africa. When not grubbing about with computers, he enjoys taking the pirogue for day trips to the local islands near Conakry with his wife, Paula.
|
||||
|
||||
442
Zim/Utils/DNS.txt
Normal file
@@ -0,0 +1,442 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
|
||||
====== DNS ======
|
||||
Created Sunday 27 March 2011
|
||||
|
||||
全球路由DNS服务器
|
||||
|
||||
全球只有13台路由DNS根服务器,在13台路由服务器中,名字分别为“A”至“M”,其中10台设置在美国,另外各有一台设置于英国、瑞典和日本。下表是这些机器的管理单位、设置地点及最新的IP地址。
|
||||
|
||||
名称 管理单位及设置地点 IP地址
|
||||
A INTERNIC.NET(美国,弗吉尼亚州) 198.41.0.4
|
||||
B 美国信息科学研究所(美国,加利弗尼亚州) 128.9.0.107
|
||||
C PSINet公司(美国,弗吉尼亚州) 192.33.4.12
|
||||
D 马里兰大学(美国马里兰州) 128.8.10.90
|
||||
E 美国航空航天管理局[NASA](美国加利弗尼亚州) 192.203.230.10
|
||||
F 因特网软件联盟(美国加利弗尼亚州) 192.5.5.241
|
||||
G 美国国防部网络信息中心(美国弗吉尼亚州) 192.112.36.4
|
||||
H 美国陆军研究所(美国马里兰州) 128.63.2.53
|
||||
I Autonomica公司(瑞典,斯德哥尔摩) 192.36.148.17
|
||||
J VeriSign公司(美国,弗吉尼亚州) 192.58.128.30
|
||||
K RIPE NCC(英国,伦敦) 193.0.14.129
|
||||
L IANA (美国,弗吉尼亚州) 198.32.64.12
|
||||
|
||||
|
||||
http://www.nuo.cn/domain1-3.php
|
||||
1、什么是DNS?
|
||||
|
||||
'''
|
||||
DNS是指:域名服务器(Domain Name Server)。在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,DNS就是进行域名解析的服务器。
|
||||
'''
|
||||
|
||||
2、为什么要注册DNS,有什么意义?
|
||||
|
||||
'''
|
||||
申请了DNS后,客户可以自己为域名作解析,或增设子域名.客户申请DNS时,建议客户一次性申请两个。
|
||||
'''
|
||||
|
||||
3、DNS注册成功需要多长时间?
|
||||
|
||||
'''
|
||||
在系统中提交注册DNS的申请,款到后注册的时间为2个工作日左右。
|
||||
'''
|
||||
|
||||
4、域名修改DNS是否收费?
|
||||
|
||||
'''
|
||||
国际英文域名、国内英文域名可以修改DNS,这项服务是免费的。
|
||||
'''
|
||||
|
||||
5、为什么DNS注册成功,但仍无法使用?
|
||||
|
||||
'''
|
||||
注册DNS服务器,必须同时在该域名的DNS服务器上,为将要进行注册的DNS服务器主机名设置好域名解析,解析生效且注册成功后,新注册的DNS服务器才可以正式使用。
|
||||
'''
|
||||
|
||||
'''
|
||||
例如:要注册名为 dns1.abc.com(IP: 1.1.1.1)和 dns2.abc.com(IP: 2.2.2.2)的DNS服务器,则在提交注册申请后,须尽快在abc.com的现DNS服务器上,设置dns1.abc.com指向1.1.1.1,dns2.abc.com指向2.2.2.2。另外如果将来abc.com变更DNS服务器了,也要在新的DNS服务器上设置以上两条记录,DNS才能继续使用。
|
||||
'''
|
||||
|
||||
6、怎样检查域名的DNS是否已经设置为有效的DNS服务器?
|
||||
|
||||
'''
|
||||
您可以在DNS-DIY 2.0操作平台页面的右边区域,来检查DNS是否设置正确。或者在域名列表里也可以看到DNS是否正确。
|
||||
'''
|
||||
|
||||
'''
|
||||
如果您要修改域名的DNS需要到注册商的域名管理界面操作。
|
||||
'''
|
||||
|
||||
7、已经在注册商修改了DNS,为什么DNS检查的还是旧的DNS?
|
||||
|
||||
'''
|
||||
我们的DNS检查是根据DNS的根服务器的当前数据为依据的,在注册商修改DNS可能需要12-72小时才能反映在根服务器上。域名解析是否能生效,以我们的DNS检查为准。
|
||||
'''
|
||||
|
||||
|
||||
|
||||
域名注册-分类
|
||||
英文域名注册
|
||||
由于Internet最初是在美国发源的,因此最早的域名并无国家标识,人们按用途把它们分为几个大类,它们分别以不同的后缀结尾:.com(用于商业公司);.net(用于网络服务);.org(用于组织协会等);.gov(用于政府部门); .edu(用于教育机构);.mil(用于军事领域);.int(用于国际组织)。最初的域名体系也主要供美国使用,因此美国的企业、机构、政府部门等所用的都是“国际域名”,随着Internet向全世界的发展,.edu、.gov、.mil一般只被美国专用外,另外三类常用的域名.com、.org、.net则成为全世界通用,因此这类域名通常称为“国际域名”,直到现在仍然为世界各国所应用。
|
||||
地理顶级域名,共有243个国家和地区的代码,例如.CN代表中国,.UK代表英国。这样以.CN为后缀的域名就相应地叫做“国内域名”。与国际域名的后缀命名类似,在.cn顶级域名下也分设了不同意义的二级域,主要包括类别域和行政区域,这样就是通常说的二级域名:可以在.com.cn或.net.cn等二级域下三级注册域名,三级域名可分为两类:类别域名和行政区划域名。
|
||||
类别域名是依照申请机构的性质划分出来的域名,具体包括:AC 科研机构、COM 工、商、金融等企业、EDU 教育机构、GOV 政府部门、NET 互联网络、接入网络的信息中心(NIC)和运行中心(NOC))、ORG 各种非盈利性的组织。
|
||||
行政区划域名是按照中国的各个行政区划划分而成的,其划分标准依照原国家技术监督局发布的国家标准而定,包括“行政区域名”34个,适用于中国的各省、自治区、直辖市。
|
||||
中国34个顶级域名之行政区域名分别为:
|
||||
BJ-北京市; SH-上海市; TJ-天津市;
|
||||
CQ-重庆市; HE-河北省; SX-山西省;
|
||||
NM -内蒙古自治区; LN-辽宁省; JL-吉林省;
|
||||
HL-黑龙江省; JS-江苏省; ZJ-浙江省;
|
||||
AH-安徽省; FJ-福建省; JX-江西省;
|
||||
SD-山东省; HA-河南省; HB-湖北省;
|
||||
HN-湖南省; GD-广东省; GX-广西壮族自治区;
|
||||
HI-海南省; SC-四川省; GZ-贵州省;
|
||||
YN -云南省; XZ-西藏自治区; SN-陕西省;
|
||||
GS-甘肃省; QH-青海省; NX-宁夏回族自治区;
|
||||
XJ-新疆维吾尔自治区;
|
||||
TW-台湾; HK-香港; MO-澳门。[1]
|
||||
域名注册-期限
|
||||
域名注册管理体系
|
||||
域名注册过期删除期限
|
||||
1、国际域名过期30天内可以提交续费试试但不保证成功,过期后30-60天为赎回期(redemptionPeriod)可以交赎回费用进行赎回,但是也不保证成功,过期后 60-75天为删除期(pendingDelete)这种状态只有等待删除后重新注册,建议您在域名到期之前30天联系"太给网络"办理相关续费手续。
|
||||
2、如果国际域名过期后进入赎回期状态:(REDEMPTION PERIOD),您只能选择办理赎回或者等待域名释放后重新注册。
|
||||
国内顶级域名(如:.cn)的注册到期删除、续费及赎回规则:
|
||||
根据中国互联网络信息中心(CNNIC)的要求,从2007年12月20日起,CN英文域名的续费规则进行了相应的调整:CN英文域名到期未办理续费业务,域名会进入续费期,在此期间您的域名将可能暂停原来的解析,直到您成功续费后方可恢复。cn到期后30天可续费。续费期内如仍未完成续费,域名会进入高价赎回期,域名状态变为“pendingDelete”,无法进行信息修改、转移和解析等操作。如您仍想要该域名,则需要按规定另外缴纳赎回域名的费用;若赎回期内域名没有被赎回,赎回期结束后60-75天为删除期,该域名将被删除。
|
||||
|
||||
如何进行域名解析?
|
||||
发布时间2010-05-22
|
||||
首先登录您的帐号,在您的域名业务列表中,选择要解析的域名
|
||||
|
||||
1、选择“解析”即可进入续费页面。
|
||||
2、登陆解析页面后您可以根据一下文档对您的域名进行管理。
|
||||
(1)新建子域名 - 子域名 填写您的子域名。如:abc.123.com ;填写 “abc”即可。 - 类 型 默认为“IP地址” - 数 据 填写子域名所绑定的IP地址。如:203.171.230.1
|
||||
(2)子域名 - 数 据 填写域名所绑定的IP地址。如:203.171.230.1 点击“更新”保存设置。
|
||||
(3)NS记录 - 服务器名 如果您使用我公司的DNS域名解析服务器,请确定此处为: dns1.zzidc.com. 和 dns2.zzidc.com
|
||||
注意;当您对域名进行修改或创建以后,您需要点击“重新加载”您修改的信息才可以生效。
|
||||
·什么是DNS记录?
|
||||
每个域名解析都应当有至少一个DNS服务器。DNS服务器记录应当填写主机名,而且是正式注册过的合法的DNS服务器。在修改DNS记录时请务必慎重,否则有可能造成域名不能正常解析。
|
||||
·什么是邮件记录?
|
||||
每个域名解析都应当有至少一个邮件服务器记录。邮件服务器记录应当填写主机名。通常是mail,然后在下面的子域名解析中有一个mail子域名的IP地址记录,最终指向邮件服务器的IP。 ·什么是IP地址记录?
|
||||
IP地址记录就是将一个子域名解析到某个IP地址。常用的IP地址记录有www等。同一个子域名可以有多个IP地址记录。此时,DNS服务器会随机回答多个IP当中的一个,通常用于负载均衡。
|
||||
·什么是别名记录?
|
||||
别名记录就是将一个子域名解析为另一个网络名称的别名。
|
||||
·相对主机名vs绝对主机名?
|
||||
域名解析的NS,邮件和别名记录都应当填写主机名。在填写主机名时,如果最后不加“.”,就是相对主机名,加“.”的是绝对主机名。相对主机名的实际地址要加上域名才是真正的主机名。如abc.com的邮件记戮繿il,实际上是mail.abc.com.。
|
||||
·我的域名abc.com的邮件要发到另外的邮件服务器,应该怎么做?
|
||||
如果直接知道对方瞪鯬,邮件记录不用更改,只改mail子域名的IP地址记录为对方瞪鯬;如果只知道对方的主机名如mail.otherdomain.com,或者对方的邮件服务器有好多IP,那么,需要把邮件记录改为mail.otherdomain.com.,注意最后的“.”。
|
||||
·泛解析应该怎么做?
|
||||
泛解析,又称无限子域名,就是*.domain.com都解析到某个IP。可以在添加子域名时在子域名栏中填“*”,这样即使不显性地添加abc.domain.com,也可以解析。
|
||||
|
||||
|
||||
管理专题—我可以自主修改域名的哪些信息?
|
||||
发布时间2010-06-01
|
||||
国际域名信息包括:域名所有者信息、域名管理联系人信息、域名技术联系人信息和域名缴费人信息,您可以通过域名管理界面—修改联系人信息来修改,除了注册所有者的单位名称的中英文以外,其他信息都可以修改。
|
||||
注:联系人信息,应该保证信息的真实、有效、完整,不能不存在的、非法的信息。如:
|
||||
Whois Server Version 2.0
|
||||
|
||||
Domain names in the .com and .net domains can now be registered
|
||||
with many different competing registrars. Go to http://www.internic.net
|
||||
for detailed information.
|
||||
|
||||
Domain Name: ZZIDC.COM
|
||||
Registrar: HICHINA ZHICHENG TECHNOLOGY LTD.
|
||||
Whois Server: grs.hichina.com
|
||||
Referral URL: http://www.net.cn
|
||||
Name Server: DNS7.HICHINA.COM
|
||||
Name Server: DNS8.HICHINA.COM
|
||||
Status: ok
|
||||
Updated Date: 20-mar-2010
|
||||
Creation Date: 23-apr-2004
|
||||
Expiration Date: 23-apr-2013
|
||||
>>> Last update of whois database: Tue, 21 Sep 2010 15:30:06 UTC <<<
|
||||
|
||||
NOTICE: The expiration date displayed in this record is the date the
|
||||
registrar's sponsorship of the domain name registration in the registry is
|
||||
currently set to expire. This date does not necessarily reflect the expiration
|
||||
date of the domain name registrant's agreement with the sponsoring
|
||||
registrar. Users may consult the sponsoring registrar's Whois database to
|
||||
view the registrar's reported date of expiration for this registration.
|
||||
|
||||
TERMS OF USE: You are not authorized to access or query our Whois
|
||||
database through the use of electronic processes that are high-volume and
|
||||
automated except as reasonably necessary to register domain names or
|
||||
modify existing registrations; the Data in VeriSign Global Registry
|
||||
Services' ("VeriSign") Whois database is provided by VeriSign for
|
||||
information purposes only, and to assist persons in obtaining information
|
||||
about or related to a domain name registration record. VeriSign does not
|
||||
guarantee its accuracy. By submitting a Whois query, you agree to abide
|
||||
by the following terms of use: You agree that you may use this Data only
|
||||
for lawful purposes and that under no circumstances will you use this Data
|
||||
to: (1) allow, enable, or otherwise support the transmission of mass
|
||||
unsolicited, commercial advertising or solicitations via e-mail, telephone,
|
||||
or facsimile; or (2) enable high volume, automated, electronic processes
|
||||
that apply to VeriSign (or its computer systems). The compilation,
|
||||
repackaging, dissemination or other use of this Data is expressly
|
||||
prohibited without the prior written consent of VeriSign. You agree not to
|
||||
use electronic processes that are automated and high-volume to access or
|
||||
query the Whois database except as reasonably necessary to register
|
||||
domain names or modify existing registrations. VeriSign reserves the right
|
||||
to restrict your access to the Whois database in its sole discretion to ensure
|
||||
operational stability. VeriSign may restrict or terminate your access to the
|
||||
Whois database for failure to abide by these terms of use. VeriSign
|
||||
reserves the right to modify these terms at any time.
|
||||
|
||||
The Registry database contains ONLY .COM, .NET, .EDU domains and
|
||||
Registrars.Domain Name ..................... zzidc.com
|
||||
Name Server ..................... dns7.hichina.com
|
||||
dns8.hichina.com
|
||||
Registrant ID ................... hc229769019-cn
|
||||
Registrant Name ................. xiao long
|
||||
Registrant Organization ......... xiao long yang
|
||||
Registrant Address .............. HuaYuanLu 144Hao XinXiDaSha 701
|
||||
Registrant City ................. zhengzhou
|
||||
Registrant Province/State ....... henan
|
||||
Registrant Postal Code .......... 450002
|
||||
Registrant Country Code ......... CN
|
||||
Registrant Phone Number ......... +86.037163335506 -
|
||||
Registrant Fax .................. +86.037163335504 -
|
||||
Registrant Email ................ @vip.sina.com
|
||||
Technical ID .................... hichina001-cn
|
||||
Technical Name .................. hichina
|
||||
Technical Organization .......... HiChina Web Solutions Limited
|
||||
Technical Address ............... 3/F., HiChina Mansion
|
||||
No.27 Gulouwai Avenue
|
||||
Dongcheng District
|
||||
Technical City .................. Beijing
|
||||
Technical Province/State ........ Beijing
|
||||
Technical Postal Code ........... 100011
|
||||
Technical Country Code .......... CN
|
||||
Technical Phone Number .......... +86.01064242299 -
|
||||
Technical Fax ................... +86.01064258796 -
|
||||
Technical Email ................. @hichina.com
|
||||
Administrative ID ............... hichina001-cn
|
||||
Administrative Name ............. hichina
|
||||
Administrative Organization ..... HiChina Web Solutions Limited
|
||||
Administrative Address .......... 3/F., HiChina Mansion
|
||||
No.27 Gulouwai Avenue
|
||||
Dongcheng District
|
||||
Administrative City ............. Beijing
|
||||
Administrative Province/State ... Beijing
|
||||
Administrative Postal Code ...... 100011
|
||||
Administrative Country Code ..... CN
|
||||
Administrative Phone Number ..... +86.01064242299 -
|
||||
Administrative Fax .............. +86.01064258796 -
|
||||
Administrative Email ............ @hichina.com
|
||||
Billing ID ...................... hichina001-cn
|
||||
Billing Name .................... hichina
|
||||
Billing Organization ............ HiChina Web Solutions Limited
|
||||
Billing Address ................. 3/F., HiChina Mansion
|
||||
No.27 Gulouwai Avenue
|
||||
Dongcheng District
|
||||
Billing City .................... Beijing
|
||||
Billing Province/State .......... Beijing
|
||||
Billing Postal Code ............. 100011
|
||||
Billing Country Code ............ CN
|
||||
Billing Phone Number ............ +86.01064242299 -
|
||||
Billing Fax ..................... +86.01064258796 -
|
||||
Billing Email ................... @hichina.com
|
||||
Expiration Date ................. 2013-04-23 05:52:41
|
||||
|
||||
|
||||
|
||||
域名状态查询
|
||||
|
||||
作者:客服中心 文章来源:中国万网 点击数:10848 更新时间:2007-8-24
|
||||
|
||||
为便于我们查询域名的状态和信息,向大家推荐以下查询地址:
|
||||
|
||||
常用官方whois地址
|
||||
VeriSign: .com/.net/.cc/.tv/.edu/.jobs
|
||||
http://registrar.verisign-grs.com/cgi-bin/whois
|
||||
CNNIC 国内英文域名: .cn
|
||||
http://ewhois.cnnic.cn/
|
||||
CNNIC 国内中文域名: .中国/.网络/.公司
|
||||
http://cwhois.cnnic.cn/
|
||||
|
||||
另外提供cn域名各个状态说明:
|
||||
以client开头的状态表示由客户端(注册商)可以增加的状态
|
||||
以server开头的状态表示服务器端(CNNIC)操作增加的状态
|
||||
既不以client开头也不以server开头的状态由服务器端管理
|
||||
域名的状态解释:
|
||||
|
||||
ok 正常状态
|
||||
inactive 非激活状态(注册的时候没有填写域名服务器,不能进行解析)
|
||||
clientDeleteProhibited 禁止删除
|
||||
serverDeleteProhibited 禁止删除
|
||||
clientUpdateProhibited 禁止修改
|
||||
serverUpdateProhibited 禁止修改
|
||||
pendingDelete 正在删除过程中
|
||||
pendingTransfer 正在转移过程中
|
||||
clientTransferProhibited 禁止转移
|
||||
serverTransferProhibited 禁止转移
|
||||
clientRenewProhibited 禁止续费
|
||||
serverRenewProhibited 禁止续费
|
||||
clientHold 停止解析
|
||||
serverHold 停止解析
|
||||
pendingVerification 注册信息正在确认过程中
|
||||
|
||||
晕哟,现在快5点了,刚才4:30的时候想趁现在.cn域名只1元一年我也想抢注个好点的域名,在cnnic发现了几个好点的域名很有几个,都还蛮可以,可是在4:30的时候只提交成功了199199.cn这个域名,其它好几个都没有成功.. ,那些人太快了,根本就抢不赢他们,更可恨的是最后来查199199.cn也被捷足先登了,还害得我到5点了还没有睡觉,哎 ,以后再也不去抢了,他们太厉害了我只能说.
|
||||
不过以下知识我们了解了解也是好的,权当是增长点知识吧!(其实是给自己找点安慰而已 )
|
||||
国际域名状态介绍(普及域名知识)
|
||||
Active : 正常状态
|
||||
|
||||
Registry-hold: 注册局暂停,域名没有解析,不能正常使用,可以续费;
|
||||
|
||||
Registry-lock : 注册局锁定,域名有解析,正常使用,不能更改,可以续费;
|
||||
|
||||
Registrar-hold : 注册商暂停,停止解析,不能正常使用,可以续费;
|
||||
|
||||
Registrar-lock: 注册商锁定,可以正常使用,不能更改、转移;
|
||||
|
||||
Redemptionperiod: 偿还期,域名过期后由注册商申请删除域名,域名进入偿还期,偿还期30天内不能正常使用,但可以交纳赎回费用($40)恢复域名,否则进入删除期
|
||||
|
||||
Pendingretore: 域名进入偿还期后,由注册商申请恢复,交费后进入恢复期,提交报告后,域名可以恢复正常。
|
||||
|
||||
Pendingdelete: 域名30天偿还期后进入5天的删除期,删除期不允许其他人注册,此状态表明域名即将被删除释放。
|
||||
|
||||
Inactive: 域名没有解析,不能正常使用。一般是由于域名的dns没有填写,或填写不完整造成的,最少需要填写1个dns才能正常解析。
|
||||
Status: clientTransferProhibited 域名禁止转让
|
||||
Status: clientDeleteProhibited 域名禁止删除
|
||||
Status: clientUpdateProhibited 域名禁止更新
|
||||
|
||||
国内域名状态介绍:
|
||||
|
||||
Active:正常状态。域名解析正常,可以更改,可以转移;
|
||||
|
||||
Ok:正常状态。域名续费成功;
|
||||
|
||||
Pendingtransfer:转移中状态。已经由新注册商提出转入申请,等待原注册商同意转出操作。此状态不能更改任何信息,但域名解析正常。
|
||||
|
||||
Inactive:非正常状态。表明域名没有解析,无法正常使用。 PendingDelete:等待删除状态。表明域名欠费,已经停止解析。此状态从过期开始保留15天。超过15天域名被删除。
|
||||
|
||||
ClientTransferProhibited:注册商限制转移.
|
||||
域名删除时间:
|
||||
引用内容
|
||||
CN COM NET域名 删除及可注册时间
|
||||
|
||||
|
||||
CN过期后删除时间为16天 北京时间早4点左右(大概是4:30开始)
|
||||
|
||||
|
||||
|
||||
COM则约75天左右 将在北京时间早2点左右开始到4点,一般删除
|
||||
|
||||
|
||||
|
||||
net65天左右 将在北京时间早2点左右开始到4点,一般删除
|
||||
|
||||
附在百度看到的解释:
|
||||
域名删除规律及域名状态解释
|
||||
分析一下域名删除规律及域名状态解释——这篇文章对于站长保护自己的域名不被恶意抢注很好帮助,值得一看。
|
||||
A、域名过期后第一阶段即域名过期后1~45天内将处于注册商保留状态。whois英文状态:REGISTRAR-HOLD。
|
||||
|
||||
B、域名过期后第二阶段即注册商保留期结束之后,域名将进入30天赎回期。whois英文状态:REDEMPTION-PERIOD。
|
||||
|
||||
C、域名过期后第三阶段即赎回期结束之后域名将进入6天的删除未决期,6天期满后域名删除。whois英文状态:PENDING-Delete。
|
||||
|
||||
D、whois英文状态:REGISTRAR-LOCK是域名锁定状态,过期后防止被转移注册商。
|
||||
|
||||
|
||||
1、比如域名aaa.com到期时间为2003年03月01日;
|
||||
|
||||
2、从2003年03月02日开始,域名的ns将会被系统自动删除,域名无法解析,注册公司会继续保留该域名30天,用户可以在这30天的期限内续费;
|
||||
|
||||
3、如果在2所述的30天期限内没有续费,即从2003年03月31日开始,域名将变成RedemptionPeriod状态,该状态将会保持30天,在此期间该域名不会掉下来,但是除了restore命令以外的所有命令对此域名无效;
|
||||
|
||||
4、域名在RedemptionPeriod状态下可以restore回来,但每restore一次需要支付费用;
|
||||
|
||||
5、如果域名在RedemptionPeriod状态下的30天没有restore,从2003.04.29开始域名变成PendingDelete状态(5天),2003年05月04日该域名将会删除。
|
||||
|
||||
VeriSign于2003年1月在其Registry Whois (.COM和.NET)中加了3个字段:
|
||||
|
||||
Status、Creation Date、Expiration Date
|
||||
|
||||
其中 Status 目前发现有8种状态,分别是:
|
||||
|
||||
1、ACTIVE:活动状态。由Registry设置;该域名可以由Registrar更改;可以续费;至少被指派一个DNS。
|
||||
|
||||
2、REGISTRY-LOCK:注册局锁定。由注册局设置;该域名不可以由注册商更改、删除;必须由注册局解除此状态才可以由注册商更改域名畔ⅲ挥蛎 梢孕 眩蝗绻 蛎 恢概芍辽僖桓鯠NS则可以包含在(域名根服务器)的区域中(可以正常使用)。
|
||||
|
||||
3、REGISTRY-HOLD:注册局保留。由注册局设置;该域名不可以由注册商更改、删除;必须由注册局解除此状态才可以由注册商更改域名信息;域名可以续费;该域名不包括在(域名根服务器)的区域中(不能正常使用)。
|
||||
|
||||
4、REGISTRAR-LOCK:注册商锁定。由该域名的原始注册商设置;该域名不可以被更改或删除;必须由注册商解除此状态才可以更改域名信息;该域名可以续费。该域名包含在(域名根服务器)的区域中(可以正常使用)。
|
||||
|
||||
5、REGISTRAR-HOLD:注册商保留。由该域名的原始注册商设置;该域名不可以被更改或删除;必须由注册商解除此状态才可以更改域名信息;该域名可以续费。该域名不包括在(域名根服务器)的区域中(不能正常使用)。
|
||||
|
||||
6、REDEMPTIONPERIOD:宽限期。当注册商向注册局提出删除域名请求后,由注册局将域名设置称此状态,不过,条件是该域名已经注册了5天以上(如果该域名注册时间不足5天,则立即删除);该域名不包括在(域名根服务器)的区域中(不能正常使用);该域名不可以被更改或清除,只可以被恢复;任何其他注册商提出对此域名的更改或其他请求都将被拒绝;该状态最多保持30天。
|
||||
|
||||
7、PENDINGRESTORE:恢复未决。当注册商提出将处于REDEMPTIONPERIOD的域名恢复请求后,由注册局设置;该域名包含在(域名根服务器)的区域中(可以正常使用);注册商提出的更改或任何其他请求都将被拒绝;在7天之内,有注册商向注册局提供必需的恢复文件,如果注册商在7天之内提供了这些文件,该域名将被置为ACTIVE状态,否则,该域名将重新返回到REDEMPTIONPERIOD状态。
|
||||
|
||||
8、PENDINGDelete:删除未决。如果一个域名在被设置成REDEMPTIONPERIOD状态期间内,注册商没有提出恢复请求,那么,域名将被置于PENDINGDelete状态,注册商对此域名的任何请求都将被拒绝;5天之后清除。
|
||||
、.COM/.NET域名状态包括:
|
||||
|
||||
(1) ACTIVE(激活状态):域名处于此状态时可以正常使用、正常续费、可以转移、可以更改DNS和域名信息,在此状态时用户还可自行设置为锁定状态。
|
||||
|
||||
(2) Customer-LOCK(用户锁定):当域名在ACTIVE状态时可由用户自行设置,用户可自行取消,域名处于此状态时可以正常使用、正常续费、不可以转移、不可以更改DNS和域名信息,此状态也可以由注册商取消;
|
||||
|
||||
(3) Registrar-LOCK(注册商锁定):由注册商设置,用户不能取消。域名处于此状态时可以正常使用、正常续费、不可以转移、不可以更改DNS和域名信息,此状态也可以由注册商取消;
|
||||
|
||||
(4) Autorenew-HOLD(欠费保留):由注册商设置,用户不能取消。域名由于过期欠费而被设置为此状态,域名处于此状态时不能正常使用、不可以被更改或删除;必须续费后才能自动解除此状态。
|
||||
|
||||
(5) Registrar-HOLD(注册商保留):由注册商设置,用户不能取消。域名处于此状态时不能正常使用、不可以删除、不可以转移、更改DNS和域名信息,可以续费,必须由注册商解除此状态。
|
||||
|
||||
2、.ORG域名状态包括:
|
||||
(1) OK(正常状态):域名处于此状态时可以正常使用、正常续费、可以转移、可以更改DNS和域名信息,此状态不与下面的其他状态同时存在。
|
||||
|
||||
(2) Customer-DeleteProhibited(用户限制删除):由用户自行设定的限制删除,用户可自行取消,域名处于此状态时可以正常使用、正常管理、正常续费、不可以被删除,此状态也可以由注册商取消,同时,若域名欠费后会自动按删除周期删除;
|
||||
|
||||
(3) Registrar-DeleteProhibited(注册商限制删除):由注册商设定的限制删除,域名处于此状态时可以正常使用、正常管理、正常续费、不可以被删除,此状态不可以由用户自行取消,同时,若域名欠费后会自动按删除周期删除;
|
||||
|
||||
(4) Customer-TransferProhibited(用户限制转移):由用户自行设定的限制转移,用户可自行取消,域名处于此状态时不可以转移、可以正常使用、正常管理、正常续费,此状态也可以由注册商取消;
|
||||
|
||||
(5) Registrar-TransferProhibited(注册商限制转移):由注册商设定的限制转移,域名处于此状态时不可以转移、可以正常使用、正常管理、正常续费,用户不可以自行取消该状态;
|
||||
|
||||
(6) Customer-UpdateProhibited(用户限制更改):由用户自行设定的限制更改,用户可自行取消,域名处于此状态时不可以更改域名信息和DNS、可以正常使用、正常续费,此状态也可以由注册商取消;
|
||||
|
||||
(7) Registrar-UpdateProhibited(注册商限制更改):由注册商设定的限制更改,域名处于此状态时不可以更改域名信息和DNS、可以正常使用、正常续费,用户不可以自行取消该状态;
|
||||
|
||||
(8) Autorenew-HOLD(欠费保留):由注册商设置,用户不能取消。域名由于过期欠费而被设置为此状态,域名处于此状态时不能正常使用、不可以被更改或删除;必须续费后才能自动解除此状态。
|
||||
|
||||
(9) Registrar-HOLD(注册商保留):由注册商设置,用户不能取消。域名处于此状态时不能正常使用、不可以删除、不可以转移,可以续费,必须由注册商解除此状态。
|
||||
|
||||
国际域名删除域名的规律:
|
||||
|
||||
域名过期后第一阶段
|
||||
域名过期后1~45天内
|
||||
将处于注册商保留状态
|
||||
whois英文状态:REGISTRAR-HOLD
|
||||
|
||||
域名过期后第二阶段
|
||||
注册商保留期结束之后
|
||||
域名将进入30天赎回期
|
||||
whois英文状态:REDEMPTION-PERIOD
|
||||
|
||||
域名过期后第三阶段
|
||||
赎回期结束之后域名将
|
||||
进入6天的删除未决期
|
||||
6天期满后域名删除
|
||||
|
||||
解析专题—域名做了指向为什么还无法访问?
|
||||
发布时间2010-06-01
|
||||
域名解析的过程非常复杂,是一个全球域名系统逐级更新的方式,加上用户上网调用的DNS服务器也有缓存,只有缓存过期重新读取根数据库的解析记录,解析的IP地址才能被浏览者看到,所以即使网络时代的所有解析服务都是立即生效的,但是如果要正常访问,还需要各地服务器的刷新,如果是修改DNS,一般刷新时间是24-48小时,如果是修改的指向,一般是1-2小时。(和各地服务器刷新速度有关)
|
||||
|
||||
解析专题—域名记录能添加哪些?需要收费吗?
|
||||
发布时间2010-06-01
|
||||
解析记录可以自由添加和修改、删除,包括:A记录、MX记录、CNAME记录和URL转发、泛域名解析。不需要收费。
|
||||
|
||||
解析专题—解析记录有个数限制吗?
|
||||
发布时间2010-06-01
|
||||
有个数限制,在解析各项记录加起来总数不能超过100条。
|
||||
|
||||
域名注册成功后还可以申请那些后续服务?
|
||||
发布时间2010-06-01
|
||||
域名注册成功以后,您可以申请一个虚拟主机来存放您的网页,以便您的客户可以访问到您的网站。
|
||||
您可以登录http://www.abcde.com.cn/-电信主机,选择一款适合您的虚拟主机,与您的域名绑定,然后上传您制作好的网页。这样您建立的网站就可以被用户访问了。
|
||||
为了业务的开展,您还需要一个企业邮箱,可以登录http://www.abcde.com.cn/-企业邮局,选择一款邮箱,申请成功后,就可以以您的域名为后缀,收发邮件了。
|
||||
|
||||
|
||||
如何确定我所注册的域名已经生效?
|
||||
发布时间2010-06-01
|
||||
您可以通过http://www.internic.net%E6%A0%B9%E5%BA%93%E7%BD%91%E7%AB%99%EF%BC%8C%E7%82%B9%E5%87%BB%E7%BD%91%E7%AB%99%E4%B8%8A%E7%9A%84%E2%80%9Dwhois%E2%80%9D%EF%BC%8C%E5%8D%B3%E5%8F%AF%E8%BF%9B%E5%85%A5%E6%9F%A5%E8%AF%A2%E3%80%82%E6%AD%A4%E5%A4%84%E5%8F%AA%E8%83%BD%E6%9F%A5%E8%AF%A2%E5%88%B0%E5%9F%9F%E5%90%8D%E6%89%80%E5%B1%9E%E6%9C%8D%E5%8A%A1%E5%95%86%E3%80%81%E7%94%9F%E6%95%88%E6%97%A5%E6%9C%9F%E3%80%81%E5%88%B0%E6%9C%9F%E6%97%A5%E8%B5%B7%E3%80%81DNS%E3%80%81%E6%9C%8D%E5%8A%A1%E5%95%86WHOIS地址等信息,无法查询域名的具体联系人信息。
|
||||
__http://www.internic.net/whois.html__
|
||||
|
||||
425
Zim/Utils/DNS.txt~
Normal file
@@ -0,0 +1,425 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-03-27T19:45:07+08:00
|
||||
|
||||
====== DNS ======
|
||||
Created Sunday 27 March 2011
|
||||
|
||||
全球路由DNS服务器
|
||||
|
||||
全球只有13台路由DNS根服务器,在13台路由服务器中,名字分别为“A”至“M”,其中10台设置在美国,另外各有一台设置于英国、瑞典和日本。下表是这些机器的管理单位、设置地点及最新的IP地址。
|
||||
|
||||
名称 管理单位及设置地点 IP地址
|
||||
A INTERNIC.NET(美国,弗吉尼亚州) 198.41.0.4
|
||||
B 美国信息科学研究所(美国,加利弗尼亚州) 128.9.0.107
|
||||
C PSINet公司(美国,弗吉尼亚州) 192.33.4.12
|
||||
D 马里兰大学(美国马里兰州) 128.8.10.90
|
||||
E 美国航空航天管理局[NASA](美国加利弗尼亚州) 192.203.230.10
|
||||
F 因特网软件联盟(美国加利弗尼亚州) 192.5.5.241
|
||||
G 美国国防部网络信息中心(美国弗吉尼亚州) 192.112.36.4
|
||||
H 美国陆军研究所(美国马里兰州) 128.63.2.53
|
||||
I Autonomica公司(瑞典,斯德哥尔摩) 192.36.148.17
|
||||
J VeriSign公司(美国,弗吉尼亚州) 192.58.128.30
|
||||
K RIPE NCC(英国,伦敦) 193.0.14.129
|
||||
L IANA (美国,弗吉尼亚州) 198.32.64.12
|
||||
|
||||
|
||||
http://www.nuo.cn/domain1-3.php
|
||||
1、什么是DNS?
|
||||
|
||||
DNS是指:域名服务器(Domain Name Server)。在Internet上域名与IP地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识IP地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,DNS就是进行域名解析的服务器。
|
||||
|
||||
2、为什么要注册DNS,有什么意义?
|
||||
|
||||
申请了DNS后,客户可以自己为域名作解析,或增设子域名.客户申请DNS时,建议客户一次性申请两个。
|
||||
|
||||
3、DNS注册成功需要多长时间?
|
||||
|
||||
在系统中提交注册DNS的申请,款到后注册的时间为2个工作日左右。
|
||||
|
||||
4、域名修改DNS是否收费?
|
||||
|
||||
国际英文域名、国内英文域名可以修改DNS,这项服务是免费的。
|
||||
|
||||
5、为什么DNS注册成功,但仍无法使用?
|
||||
|
||||
注册DNS服务器,必须同时在该域名的DNS服务器上,为将要进行注册的DNS服务器主机名设置好域名解析,解析生效且注册成功后,新注册的DNS服务器才可以正式使用。
|
||||
|
||||
例如:要注册名为 dns1.abc.com(IP: 1.1.1.1)和 dns2.abc.com(IP: 2.2.2.2)的DNS服务器,则在提交注册申请后,须尽快在abc.com的现DNS服务器上,设置dns1.abc.com指向1.1.1.1,dns2.abc.com指向2.2.2.2。另外如果将来abc.com变更DNS服务器了,也要在新的DNS服务器上设置以上两条记录,DNS才能继续使用。
|
||||
|
||||
6、怎样检查域名的DNS是否已经设置为有效的DNS服务器?
|
||||
|
||||
您可以在DNS-DIY 2.0操作平台页面的右边区域,来检查DNS是否设置正确。或者在域名列表里也可以看到DNS是否正确。
|
||||
|
||||
如果您要修改域名的DNS需要到注册商的域名管理界面操作。
|
||||
|
||||
7、已经在注册商修改了DNS,为什么DNS检查的还是旧的DNS?
|
||||
|
||||
我们的DNS检查是根据DNS的根服务器的当前数据为依据的,在注册商修改DNS可能需要12-72小时才能反映在根服务器上。域名解析是否能生效,以我们的DNS检查为准。
|
||||
|
||||
|
||||
|
||||
域名注册-分类
|
||||
英文域名注册
|
||||
由于Internet最初是在美国发源的,因此最早的域名并无国家标识,人们按用途把它们分为几个大类,它们分别以不同的后缀结尾:.com(用于商业公司);.net(用于网络服务);.org(用于组织协会等);.gov(用于政府部门); .edu(用于教育机构);.mil(用于军事领域);.int(用于国际组织)。最初的域名体系也主要供美国使用,因此美国的企业、机构、政府部门等所用的都是“国际域名”,随着Internet向全世界的发展,.edu、.gov、.mil一般只被美国专用外,另外三类常用的域名.com、.org、.net则成为全世界通用,因此这类域名通常称为“国际域名”,直到现在仍然为世界各国所应用。
|
||||
地理顶级域名,共有243个国家和地区的代码,例如.CN代表中国,.UK代表英国。这样以.CN为后缀的域名就相应地叫做“国内域名”。与国际域名的后缀命名类似,在.cn顶级域名下也分设了不同意义的二级域,主要包括类别域和行政区域,这样就是通常说的二级域名:可以在.com.cn或.net.cn等二级域下三级注册域名,三级域名可分为两类:类别域名和行政区划域名。
|
||||
类别域名是依照申请机构的性质划分出来的域名,具体包括:AC 科研机构、COM 工、商、金融等企业、EDU 教育机构、GOV 政府部门、NET 互联网络、接入网络的信息中心(NIC)和运行中心(NOC))、ORG 各种非盈利性的组织。
|
||||
行政区划域名是按照中国的各个行政区划划分而成的,其划分标准依照原国家技术监督局发布的国家标准而定,包括“行政区域名”34个,适用于中国的各省、自治区、直辖市。
|
||||
中国34个顶级域名之行政区域名分别为:
|
||||
BJ-北京市; SH-上海市; TJ-天津市;
|
||||
CQ-重庆市; HE-河北省; SX-山西省;
|
||||
NM -内蒙古自治区; LN-辽宁省; JL-吉林省;
|
||||
HL-黑龙江省; JS-江苏省; ZJ-浙江省;
|
||||
AH-安徽省; FJ-福建省; JX-江西省;
|
||||
SD-山东省; HA-河南省; HB-湖北省;
|
||||
HN-湖南省; GD-广东省; GX-广西壮族自治区;
|
||||
HI-海南省; SC-四川省; GZ-贵州省;
|
||||
YN -云南省; XZ-西藏自治区; SN-陕西省;
|
||||
GS-甘肃省; QH-青海省; NX-宁夏回族自治区;
|
||||
XJ-新疆维吾尔自治区;
|
||||
TW-台湾; HK-香港; MO-澳门。[1]
|
||||
域名注册-期限
|
||||
域名注册管理体系
|
||||
域名注册过期删除期限
|
||||
1、国际域名过期30天内可以提交续费试试但不保证成功,过期后30-60天为赎回期(redemptionPeriod)可以交赎回费用进行赎回,但是也不保证成功,过期后 60-75天为删除期(pendingDelete)这种状态只有等待删除后重新注册,建议您在域名到期之前30天联系"太给网络"办理相关续费手续。
|
||||
2、如果国际域名过期后进入赎回期状态:(REDEMPTION PERIOD),您只能选择办理赎回或者等待域名释放后重新注册。
|
||||
国内顶级域名(如:.cn)的注册到期删除、续费及赎回规则:
|
||||
根据中国互联网络信息中心(CNNIC)的要求,从2007年12月20日起,CN英文域名的续费规则进行了相应的调整:CN英文域名到期未办理续费业务,域名会进入续费期,在此期间您的域名将可能暂停原来的解析,直到您成功续费后方可恢复。cn到期后30天可续费。续费期内如仍未完成续费,域名会进入高价赎回期,域名状态变为“pendingDelete”,无法进行信息修改、转移和解析等操作。如您仍想要该域名,则需要按规定另外缴纳赎回域名的费用;若赎回期内域名没有被赎回,赎回期结束后60-75天为删除期,该域名将被删除。
|
||||
|
||||
如何进行域名解析?
|
||||
发布时间2010-05-22
|
||||
首先登录您的帐号,在您的域名业务列表中,选择要解析的域名
|
||||
|
||||
1、选择“解析”即可进入续费页面。
|
||||
2、登陆解析页面后您可以根据一下文档对您的域名进行管理。
|
||||
(1)新建子域名 - 子域名 填写您的子域名。如:abc.123.com ;填写 “abc”即可。 - 类 型 默认为“IP地址” - 数 据 填写子域名所绑定的IP地址。如:203.171.230.1
|
||||
(2)子域名 - 数 据 填写域名所绑定的IP地址。如:203.171.230.1 点击“更新”保存设置。
|
||||
(3)NS记录 - 服务器名 如果您使用我公司的DNS域名解析服务器,请确定此处为: dns1.zzidc.com. 和 dns2.zzidc.com
|
||||
注意;当您对域名进行修改或创建以后,您需要点击“重新加载”您修改的信息才可以生效。
|
||||
·什么是DNS记录?
|
||||
每个域名解析都应当有至少一个DNS服务器。DNS服务器记录应当填写主机名,而且是正式注册过的合法的DNS服务器。在修改DNS记录时请务必慎重,否则有可能造成域名不能正常解析。
|
||||
·什么是邮件记录?
|
||||
每个域名解析都应当有至少一个邮件服务器记录。邮件服务器记录应当填写主机名。通常是mail,然后在下面的子域名解析中有一个mail子域名的IP地址记录,最终指向邮件服务器的IP。 ·什么是IP地址记录?
|
||||
IP地址记录就是将一个子域名解析到某个IP地址。常用的IP地址记录有www等。同一个子域名可以有多个IP地址记录。此时,DNS服务器会随机回答多个IP当中的一个,通常用于负载均衡。
|
||||
·什么是别名记录?
|
||||
别名记录就是将一个子域名解析为另一个网络名称的别名。
|
||||
·相对主机名vs绝对主机名?
|
||||
域名解析的NS,邮件和别名记录都应当填写主机名。在填写主机名时,如果最后不加“.”,就是相对主机名,加“.”的是绝对主机名。相对主机名的实际地址要加上域名才是真正的主机名。如abc.com的邮件记戮繿il,实际上是mail.abc.com.。
|
||||
·我的域名abc.com的邮件要发到另外的邮件服务器,应该怎么做?
|
||||
如果直接知道对方瞪鯬,邮件记录不用更改,只改mail子域名的IP地址记录为对方瞪鯬;如果只知道对方的主机名如mail.otherdomain.com,或者对方的邮件服务器有好多IP,那么,需要把邮件记录改为mail.otherdomain.com.,注意最后的“.”。
|
||||
·泛解析应该怎么做?
|
||||
泛解析,又称无限子域名,就是*.domain.com都解析到某个IP。可以在添加子域名时在子域名栏中填“*”,这样即使不显性地添加abc.domain.com,也可以解析。
|
||||
|
||||
|
||||
管理专题—我可以自主修改域名的哪些信息?
|
||||
发布时间2010-06-01
|
||||
国际域名信息包括:域名所有者信息、域名管理联系人信息、域名技术联系人信息和域名缴费人信息,您可以通过域名管理界面—修改联系人信息来修改,除了注册所有者的单位名称的中英文以外,其他信息都可以修改。
|
||||
注:联系人信息,应该保证信息的真实、有效、完整,不能不存在的、非法的信息。如:
|
||||
Whois Server Version 2.0
|
||||
|
||||
Domain names in the .com and .net domains can now be registered
|
||||
with many different competing registrars. Go to http://www.internic.net
|
||||
for detailed information.
|
||||
|
||||
Domain Name: ZZIDC.COM
|
||||
Registrar: HICHINA ZHICHENG TECHNOLOGY LTD.
|
||||
Whois Server: grs.hichina.com
|
||||
Referral URL: http://www.net.cn
|
||||
Name Server: DNS7.HICHINA.COM
|
||||
Name Server: DNS8.HICHINA.COM
|
||||
Status: ok
|
||||
Updated Date: 20-mar-2010
|
||||
Creation Date: 23-apr-2004
|
||||
Expiration Date: 23-apr-2013
|
||||
>>> Last update of whois database: Tue, 21 Sep 2010 15:30:06 UTC <<<
|
||||
|
||||
NOTICE: The expiration date displayed in this record is the date the
|
||||
registrar's sponsorship of the domain name registration in the registry is
|
||||
currently set to expire. This date does not necessarily reflect the expiration
|
||||
date of the domain name registrant's agreement with the sponsoring
|
||||
registrar. Users may consult the sponsoring registrar's Whois database to
|
||||
view the registrar's reported date of expiration for this registration.
|
||||
|
||||
TERMS OF USE: You are not authorized to access or query our Whois
|
||||
database through the use of electronic processes that are high-volume and
|
||||
automated except as reasonably necessary to register domain names or
|
||||
modify existing registrations; the Data in VeriSign Global Registry
|
||||
Services' ("VeriSign") Whois database is provided by VeriSign for
|
||||
information purposes only, and to assist persons in obtaining information
|
||||
about or related to a domain name registration record. VeriSign does not
|
||||
guarantee its accuracy. By submitting a Whois query, you agree to abide
|
||||
by the following terms of use: You agree that you may use this Data only
|
||||
for lawful purposes and that under no circumstances will you use this Data
|
||||
to: (1) allow, enable, or otherwise support the transmission of mass
|
||||
unsolicited, commercial advertising or solicitations via e-mail, telephone,
|
||||
or facsimile; or (2) enable high volume, automated, electronic processes
|
||||
that apply to VeriSign (or its computer systems). The compilation,
|
||||
repackaging, dissemination or other use of this Data is expressly
|
||||
prohibited without the prior written consent of VeriSign. You agree not to
|
||||
use electronic processes that are automated and high-volume to access or
|
||||
query the Whois database except as reasonably necessary to register
|
||||
domain names or modify existing registrations. VeriSign reserves the right
|
||||
to restrict your access to the Whois database in its sole discretion to ensure
|
||||
operational stability. VeriSign may restrict or terminate your access to the
|
||||
Whois database for failure to abide by these terms of use. VeriSign
|
||||
reserves the right to modify these terms at any time.
|
||||
|
||||
The Registry database contains ONLY .COM, .NET, .EDU domains and
|
||||
Registrars.Domain Name ..................... zzidc.com
|
||||
Name Server ..................... dns7.hichina.com
|
||||
dns8.hichina.com
|
||||
Registrant ID ................... hc229769019-cn
|
||||
Registrant Name ................. xiao long
|
||||
Registrant Organization ......... xiao long yang
|
||||
Registrant Address .............. HuaYuanLu 144Hao XinXiDaSha 701
|
||||
Registrant City ................. zhengzhou
|
||||
Registrant Province/State ....... henan
|
||||
Registrant Postal Code .......... 450002
|
||||
Registrant Country Code ......... CN
|
||||
Registrant Phone Number ......... +86.037163335506 -
|
||||
Registrant Fax .................. +86.037163335504 -
|
||||
Registrant Email ................ @vip.sina.com
|
||||
Technical ID .................... hichina001-cn
|
||||
Technical Name .................. hichina
|
||||
Technical Organization .......... HiChina Web Solutions Limited
|
||||
Technical Address ............... 3/F., HiChina Mansion
|
||||
No.27 Gulouwai Avenue
|
||||
Dongcheng District
|
||||
Technical City .................. Beijing
|
||||
Technical Province/State ........ Beijing
|
||||
Technical Postal Code ........... 100011
|
||||
Technical Country Code .......... CN
|
||||
Technical Phone Number .......... +86.01064242299 -
|
||||
Technical Fax ................... +86.01064258796 -
|
||||
Technical Email ................. @hichina.com
|
||||
Administrative ID ............... hichina001-cn
|
||||
Administrative Name ............. hichina
|
||||
Administrative Organization ..... HiChina Web Solutions Limited
|
||||
Administrative Address .......... 3/F., HiChina Mansion
|
||||
No.27 Gulouwai Avenue
|
||||
Dongcheng District
|
||||
Administrative City ............. Beijing
|
||||
Administrative Province/State ... Beijing
|
||||
Administrative Postal Code ...... 100011
|
||||
Administrative Country Code ..... CN
|
||||
Administrative Phone Number ..... +86.01064242299 -
|
||||
Administrative Fax .............. +86.01064258796 -
|
||||
Administrative Email ............ @hichina.com
|
||||
Billing ID ...................... hichina001-cn
|
||||
Billing Name .................... hichina
|
||||
Billing Organization ............ HiChina Web Solutions Limited
|
||||
Billing Address ................. 3/F., HiChina Mansion
|
||||
No.27 Gulouwai Avenue
|
||||
Dongcheng District
|
||||
Billing City .................... Beijing
|
||||
Billing Province/State .......... Beijing
|
||||
Billing Postal Code ............. 100011
|
||||
Billing Country Code ............ CN
|
||||
Billing Phone Number ............ +86.01064242299 -
|
||||
Billing Fax ..................... +86.01064258796 -
|
||||
Billing Email ................... @hichina.com
|
||||
Expiration Date ................. 2013-04-23 05:52:41
|
||||
|
||||
|
||||
|
||||
域名状态查询
|
||||
|
||||
作者:客服中心 文章来源:中国万网 点击数:10848 更新时间:2007-8-24
|
||||
|
||||
为便于我们查询域名的状态和信息,向大家推荐以下查询地址:
|
||||
|
||||
常用官方whois地址
|
||||
VeriSign: .com/.net/.cc/.tv/.edu/.jobs
|
||||
http://registrar.verisign-grs.com/cgi-bin/whois
|
||||
CNNIC 国内英文域名: .cn
|
||||
http://ewhois.cnnic.cn/
|
||||
CNNIC 国内中文域名: .中国/.网络/.公司
|
||||
http://cwhois.cnnic.cn/
|
||||
|
||||
另外提供cn域名各个状态说明:
|
||||
以client开头的状态表示由客户端(注册商)可以增加的状态
|
||||
以server开头的状态表示服务器端(CNNIC)操作增加的状态
|
||||
既不以client开头也不以server开头的状态由服务器端管理
|
||||
域名的状态解释:
|
||||
|
||||
ok 正常状态
|
||||
inactive 非激活状态(注册的时候没有填写域名服务器,不能进行解析)
|
||||
clientDeleteProhibited 禁止删除
|
||||
serverDeleteProhibited 禁止删除
|
||||
clientUpdateProhibited 禁止修改
|
||||
serverUpdateProhibited 禁止修改
|
||||
pendingDelete 正在删除过程中
|
||||
pendingTransfer 正在转移过程中
|
||||
clientTransferProhibited 禁止转移
|
||||
serverTransferProhibited 禁止转移
|
||||
clientRenewProhibited 禁止续费
|
||||
serverRenewProhibited 禁止续费
|
||||
clientHold 停止解析
|
||||
serverHold 停止解析
|
||||
pendingVerification 注册信息正在确认过程中
|
||||
|
||||
晕哟,现在快5点了,刚才4:30的时候想趁现在.cn域名只1元一年我也想抢注个好点的域名,在cnnic发现了几个好点的域名很有几个,都还蛮可以,可是在4:30的时候只提交成功了199199.cn这个域名,其它好几个都没有成功.. ,那些人太快了,根本就抢不赢他们,更可恨的是最后来查199199.cn也被捷足先登了,还害得我到5点了还没有睡觉,哎 ,以后再也不去抢了,他们太厉害了我只能说.
|
||||
不过以下知识我们了解了解也是好的,权当是增长点知识吧!(其实是给自己找点安慰而已 )
|
||||
国际域名状态介绍(普及域名知识)
|
||||
Active : 正常状态
|
||||
|
||||
Registry-hold: 注册局暂停,域名没有解析,不能正常使用,可以续费;
|
||||
|
||||
Registry-lock : 注册局锁定,域名有解析,正常使用,不能更改,可以续费;
|
||||
|
||||
Registrar-hold : 注册商暂停,停止解析,不能正常使用,可以续费;
|
||||
|
||||
Registrar-lock: 注册商锁定,可以正常使用,不能更改、转移;
|
||||
|
||||
Redemptionperiod: 偿还期,域名过期后由注册商申请删除域名,域名进入偿还期,偿还期30天内不能正常使用,但可以交纳赎回费用($40)恢复域名,否则进入删除期
|
||||
|
||||
Pendingretore: 域名进入偿还期后,由注册商申请恢复,交费后进入恢复期,提交报告后,域名可以恢复正常。
|
||||
|
||||
Pendingdelete: 域名30天偿还期后进入5天的删除期,删除期不允许其他人注册,此状态表明域名即将被删除释放。
|
||||
|
||||
Inactive: 域名没有解析,不能正常使用。一般是由于域名的dns没有填写,或填写不完整造成的,最少需要填写1个dns才能正常解析。
|
||||
Status: clientTransferProhibited 域名禁止转让
|
||||
Status: clientDeleteProhibited 域名禁止删除
|
||||
Status: clientUpdateProhibited 域名禁止更新
|
||||
|
||||
国内域名状态介绍:
|
||||
|
||||
Active:正常状态。域名解析正常,可以更改,可以转移;
|
||||
|
||||
Ok:正常状态。域名续费成功;
|
||||
|
||||
Pendingtransfer:转移中状态。已经由新注册商提出转入申请,等待原注册商同意转出操作。此状态不能更改任何信息,但域名解析正常。
|
||||
|
||||
Inactive:非正常状态。表明域名没有解析,无法正常使用。 PendingDelete:等待删除状态。表明域名欠费,已经停止解析。此状态从过期开始保留15天。超过15天域名被删除。
|
||||
|
||||
ClientTransferProhibited:注册商限制转移.
|
||||
域名删除时间:
|
||||
引用内容
|
||||
CN COM NET域名 删除及可注册时间
|
||||
|
||||
|
||||
CN过期后删除时间为16天 北京时间早4点左右(大概是4:30开始)
|
||||
|
||||
|
||||
|
||||
COM则约75天左右 将在北京时间早2点左右开始到4点,一般删除
|
||||
|
||||
|
||||
|
||||
net65天左右 将在北京时间早2点左右开始到4点,一般删除
|
||||
|
||||
附在百度看到的解释:
|
||||
域名删除规律及域名状态解释
|
||||
分析一下域名删除规律及域名状态解释——这篇文章对于站长保护自己的域名不被恶意抢注很好帮助,值得一看。
|
||||
A、域名过期后第一阶段即域名过期后1~45天内将处于注册商保留状态。whois英文状态:REGISTRAR-HOLD。
|
||||
|
||||
B、域名过期后第二阶段即注册商保留期结束之后,域名将进入30天赎回期。whois英文状态:REDEMPTION-PERIOD。
|
||||
|
||||
C、域名过期后第三阶段即赎回期结束之后域名将进入6天的删除未决期,6天期满后域名删除。whois英文状态:PENDING-Delete。
|
||||
|
||||
D、whois英文状态:REGISTRAR-LOCK是域名锁定状态,过期后防止被转移注册商。
|
||||
|
||||
|
||||
1、比如域名aaa.com到期时间为2003年03月01日;
|
||||
|
||||
2、从2003年03月02日开始,域名的ns将会被系统自动删除,域名无法解析,注册公司会继续保留该域名30天,用户可以在这30天的期限内续费;
|
||||
|
||||
3、如果在2所述的30天期限内没有续费,即从2003年03月31日开始,域名将变成RedemptionPeriod状态,该状态将会保持30天,在此期间该域名不会掉下来,但是除了restore命令以外的所有命令对此域名无效;
|
||||
|
||||
4、域名在RedemptionPeriod状态下可以restore回来,但每restore一次需要支付费用;
|
||||
|
||||
5、如果域名在RedemptionPeriod状态下的30天没有restore,从2003.04.29开始域名变成PendingDelete状态(5天),2003年05月04日该域名将会删除。
|
||||
|
||||
VeriSign于2003年1月在其Registry Whois (.COM和.NET)中加了3个字段:
|
||||
|
||||
Status、Creation Date、Expiration Date
|
||||
|
||||
其中 Status 目前发现有8种状态,分别是:
|
||||
|
||||
1、ACTIVE:活动状态。由Registry设置;该域名可以由Registrar更改;可以续费;至少被指派一个DNS。
|
||||
|
||||
2、REGISTRY-LOCK:注册局锁定。由注册局设置;该域名不可以由注册商更改、删除;必须由注册局解除此状态才可以由注册商更改域名畔ⅲ挥蛎 梢孕 眩蝗绻 蛎 恢概芍辽僖桓鯠NS则可以包含在(域名根服务器)的区域中(可以正常使用)。
|
||||
|
||||
3、REGISTRY-HOLD:注册局保留。由注册局设置;该域名不可以由注册商更改、删除;必须由注册局解除此状态才可以由注册商更改域名信息;域名可以续费;该域名不包括在(域名根服务器)的区域中(不能正常使用)。
|
||||
|
||||
4、REGISTRAR-LOCK:注册商锁定。由该域名的原始注册商设置;该域名不可以被更改或删除;必须由注册商解除此状态才可以更改域名信息;该域名可以续费。该域名包含在(域名根服务器)的区域中(可以正常使用)。
|
||||
|
||||
5、REGISTRAR-HOLD:注册商保留。由该域名的原始注册商设置;该域名不可以被更改或删除;必须由注册商解除此状态才可以更改域名信息;该域名可以续费。该域名不包括在(域名根服务器)的区域中(不能正常使用)。
|
||||
|
||||
6、REDEMPTIONPERIOD:宽限期。当注册商向注册局提出删除域名请求后,由注册局将域名设置称此状态,不过,条件是该域名已经注册了5天以上(如果该域名注册时间不足5天,则立即删除);该域名不包括在(域名根服务器)的区域中(不能正常使用);该域名不可以被更改或清除,只可以被恢复;任何其他注册商提出对此域名的更改或其他请求都将被拒绝;该状态最多保持30天。
|
||||
|
||||
7、PENDINGRESTORE:恢复未决。当注册商提出将处于REDEMPTIONPERIOD的域名恢复请求后,由注册局设置;该域名包含在(域名根服务器)的区域中(可以正常使用);注册商提出的更改或任何其他请求都将被拒绝;在7天之内,有注册商向注册局提供必需的恢复文件,如果注册商在7天之内提供了这些文件,该域名将被置为ACTIVE状态,否则,该域名将重新返回到REDEMPTIONPERIOD状态。
|
||||
|
||||
8、PENDINGDelete:删除未决。如果一个域名在被设置成REDEMPTIONPERIOD状态期间内,注册商没有提出恢复请求,那么,域名将被置于PENDINGDelete状态,注册商对此域名的任何请求都将被拒绝;5天之后清除。
|
||||
、.COM/.NET域名状态包括:
|
||||
|
||||
(1) ACTIVE(激活状态):域名处于此状态时可以正常使用、正常续费、可以转移、可以更改DNS和域名信息,在此状态时用户还可自行设置为锁定状态。
|
||||
|
||||
(2) Customer-LOCK(用户锁定):当域名在ACTIVE状态时可由用户自行设置,用户可自行取消,域名处于此状态时可以正常使用、正常续费、不可以转移、不可以更改DNS和域名信息,此状态也可以由注册商取消;
|
||||
|
||||
(3) Registrar-LOCK(注册商锁定):由注册商设置,用户不能取消。域名处于此状态时可以正常使用、正常续费、不可以转移、不可以更改DNS和域名信息,此状态也可以由注册商取消;
|
||||
|
||||
(4) Autorenew-HOLD(欠费保留):由注册商设置,用户不能取消。域名由于过期欠费而被设置为此状态,域名处于此状态时不能正常使用、不可以被更改或删除;必须续费后才能自动解除此状态。
|
||||
|
||||
(5) Registrar-HOLD(注册商保留):由注册商设置,用户不能取消。域名处于此状态时不能正常使用、不可以删除、不可以转移、更改DNS和域名信息,可以续费,必须由注册商解除此状态。
|
||||
|
||||
2、.ORG域名状态包括:
|
||||
(1) OK(正常状态):域名处于此状态时可以正常使用、正常续费、可以转移、可以更改DNS和域名信息,此状态不与下面的其他状态同时存在。
|
||||
|
||||
(2) Customer-DeleteProhibited(用户限制删除):由用户自行设定的限制删除,用户可自行取消,域名处于此状态时可以正常使用、正常管理、正常续费、不可以被删除,此状态也可以由注册商取消,同时,若域名欠费后会自动按删除周期删除;
|
||||
|
||||
(3) Registrar-DeleteProhibited(注册商限制删除):由注册商设定的限制删除,域名处于此状态时可以正常使用、正常管理、正常续费、不可以被删除,此状态不可以由用户自行取消,同时,若域名欠费后会自动按删除周期删除;
|
||||
|
||||
(4) Customer-TransferProhibited(用户限制转移):由用户自行设定的限制转移,用户可自行取消,域名处于此状态时不可以转移、可以正常使用、正常管理、正常续费,此状态也可以由注册商取消;
|
||||
|
||||
(5) Registrar-TransferProhibited(注册商限制转移):由注册商设定的限制转移,域名处于此状态时不可以转移、可以正常使用、正常管理、正常续费,用户不可以自行取消该状态;
|
||||
|
||||
(6) Customer-UpdateProhibited(用户限制更改):由用户自行设定的限制更改,用户可自行取消,域名处于此状态时不可以更改域名信息和DNS、可以正常使用、正常续费,此状态也可以由注册商取消;
|
||||
|
||||
(7) Registrar-UpdateProhibited(注册商限制更改):由注册商设定的限制更改,域名处于此状态时不可以更改域名信息和DNS、可以正常使用、正常续费,用户不可以自行取消该状态;
|
||||
|
||||
(8) Autorenew-HOLD(欠费保留):由注册商设置,用户不能取消。域名由于过期欠费而被设置为此状态,域名处于此状态时不能正常使用、不可以被更改或删除;必须续费后才能自动解除此状态。
|
||||
|
||||
(9) Registrar-HOLD(注册商保留):由注册商设置,用户不能取消。域名处于此状态时不能正常使用、不可以删除、不可以转移,可以续费,必须由注册商解除此状态。
|
||||
|
||||
国际域名删除域名的规律:
|
||||
|
||||
域名过期后第一阶段
|
||||
域名过期后1~45天内
|
||||
将处于注册商保留状态
|
||||
whois英文状态:REGISTRAR-HOLD
|
||||
|
||||
域名过期后第二阶段
|
||||
注册商保留期结束之后
|
||||
域名将进入30天赎回期
|
||||
whois英文状态:REDEMPTION-PERIOD
|
||||
|
||||
域名过期后第三阶段
|
||||
赎回期结束之后域名将
|
||||
进入6天的删除未决期
|
||||
6天期满后域名删除
|
||||
|
||||
解析专题—域名做了指向为什么还无法访问?
|
||||
发布时间2010-06-01
|
||||
域名解析的过程非常复杂,是一个全球域名系统逐级更新的方式,加上用户上网调用的DNS服务器也有缓存,只有缓存过期重新读取根数据库的解析记录,解析的IP地址才能被浏览者看到,所以即使网络时代的所有解析服务都是立即生效的,但是如果要正常访问,还需要各地服务器的刷新,如果是修改DNS,一般刷新时间是24-48小时,如果是修改的指向,一般是1-2小时。(和各地服务器刷新速度有关)
|
||||
|
||||
解析专题—域名记录能添加哪些?需要收费吗?
|
||||
发布时间2010-06-01
|
||||
解析记录可以自由添加和修改、删除,包括:A记录、MX记录、CNAME记录和URL转发、泛域名解析。不需要收费。
|
||||
|
||||
解析专题—解析记录有个数限制吗?
|
||||
发布时间2010-06-01
|
||||
有个数限制,在解析各项记录加起来总数不能超过100条。
|
||||
|
||||
域名注册成功后还可以申请那些后续服务?
|
||||
发布时间2010-06-01
|
||||
域名注册成功以后,您可以申请一个虚拟主机来存放您的网页,以便您的客户可以访问到您的网站。
|
||||
您可以登录http://www.abcde.com.cn/-电信主机,选择一款适合您的虚拟主机,与您的域名绑定,然后上传您制作好的网页。这样您建立的网站就可以被用户访问了。
|
||||
为了业务的开展,您还需要一个企业邮箱,可以登录http://www.abcde.com.cn/-企业邮局,选择一款邮箱,申请成功后,就可以以您的域名为后缀,收发邮件了。
|
||||
|
||||
|
||||
如何确定我所注册的域名已经生效?
|
||||
发布时间2010-06-01
|
||||
您可以通过http://www.internic.net%E6%A0%B9%E5%BA%93%E7%BD%91%E7%AB%99%EF%BC%8C%E7%82%B9%E5%87%BB%E7%BD%91%E7%AB%99%E4%B8%8A%E7%9A%84%E2%80%9Dwhois%E2%80%9D%EF%BC%8C%E5%8D%B3%E5%8F%AF%E8%BF%9B%E5%85%A5%E6%9F%A5%E8%AF%A2%E3%80%82%E6%AD%A4%E5%A4%84%E5%8F%AA%E8%83%BD%E6%9F%A5%E8%AF%A2%E5%88%B0%E5%9F%9F%E5%90%8D%E6%89%80%E5%B1%9E%E6%9C%8D%E5%8A%A1%E5%95%86%E3%80%81%E7%94%9F%E6%95%88%E6%97%A5%E6%9C%9F%E3%80%81%E5%88%B0%E6%9C%9F%E6%97%A5%E8%B5%B7%E3%80%81DNS%E3%80%81%E6%9C%8D%E5%8A%A1%E5%95%86WHOIS地址等信息,无法查询域名的具体联系人信息。
|
||||
__http://www.internic.net/whois.html__
|
||||
|
||||
185
Zim/Utils/GPG.txt
Normal file
@@ -0,0 +1,185 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-29T18:21:52+08:00
|
||||
|
||||
====== GPG ======
|
||||
Created Thursday 29 December 2011
|
||||
http://wowubuntu.com/gpg.html
|
||||
加密:公钥加密,私钥解密[数据保密性]
|
||||
数字签名:私钥加密,公钥解密[身份认证][数据完整性][不可抵赖性]
|
||||
|
||||
===== GPG 加密解密简明教程 =====
|
||||
10 一2011
|
||||
# 作者: riku / 本文采用CC BY-NC-SA 2.5协议授权,转载请注明本文链接。
|
||||
|
||||
大家都知道,互联网上充斥着大量的明文传输方式,可以说绝对是不安全地带。那么,我们如何保证在不安全的互联网中更可靠的传输重要数据呢?个人认为最好的方式之一就是使用 GPG 工具进行加密。此文只是简单介绍了 GPG 的常规用法,重在推广和普及 GPG 加密工具,详细的使用请参见 GPG 手册。
|
||||
|
||||
# 名词解释
|
||||
|
||||
RSA / DSA / ElGamal : 是指加密算法
|
||||
|
||||
GPG :(全称 GnuPG ) 是一款__非对称加密__(PGP)的免费软件,非对称加密方式简单讲就是指用公钥加密文件,用私钥解密文件。如果你想给谁发送加密信息,首先你要得到他的公钥,然后通过该公钥加密后传给他,对方利用自已的私钥就可解密并读取文件了。
|
||||
|
||||
# 配置文件介绍
|
||||
|
||||
GPG 配置文件目录:~/.gnupg
|
||||
|
||||
~/.gnupg/gpg.conf – 配置文件
|
||||
~/.gnupg/trustdb.gpg –** 信任库**
|
||||
~/.gnupg/pubring.gpg – **公钥库**
|
||||
~/.gnupg/secring.gpg –** 私钥库**
|
||||
|
||||
====== # 基本操作 ======
|
||||
|
||||
===== 1 生成密钥对 =====
|
||||
|
||||
gpg --gen-key
|
||||
|
||||
生成过程中会让你选择加密方式,一般选 (1) RSA and RSA (default) 就可以了,然后还需要选择加密位数、过期日期及输入**姓名**,邮件地址,备注,Passphrase(访问密码)等信息。最后你就可以干点别的事,比如上上网,玩玩游戏什么的,以便让机器生成一些随机数,回头你就可以看到密钥对已经生成完毕。
|
||||
|
||||
===== 2 传播公钥: =====
|
||||
|
||||
__导出公钥__:生成后你可以把公钥中公钥库中导出来,以便传播给你的朋友。
|
||||
|
||||
gpg --export --armor mykeyID > gpgkey.pub.asc # mykeyID 部分可以用 name 或 mail 地址代替
|
||||
|
||||
注: - -armor 表示加内容转换成可见的 __ASCII 码__输出,否则是__二进制__不可见内容。
|
||||
|
||||
现在你可以把导出的公钥通过 Email 等途径发送给你的朋友了,或者你也可以不导出公钥__直接上传公钥到密钥服务器__。
|
||||
|
||||
gpg --keyserver keyserverAddress** --send-keys **mykeyID
|
||||
|
||||
注: --keyserver 可以不加,默认为 keys.gnupg.net
|
||||
|
||||
然后只要把**公钥 ID 和服务器地址**告诉给朋友就可以了,朋友可以通过搜索你的公钥 ID ,Email 地址或名字来获取并导入你的公钥,如下:
|
||||
|
||||
gpg --keyserver keyserverAddress** --search-keys** keyid/name/Email
|
||||
|
||||
比如搜索我的:
|
||||
|
||||
gpg --keyserver keyserver.ubuntu.com --search-keys rikulu
|
||||
|
||||
===== 3 导入朋友的公钥 =====
|
||||
|
||||
当你获得朋友的公钥文件后,你首先需要导入公钥到公钥库
|
||||
|
||||
gpg --import gpgkey.pub.asc
|
||||
|
||||
或直接从公钥服务器导入
|
||||
|
||||
gpg --keyserver keyserverAddress** --recv-keys **pubkeyID
|
||||
|
||||
**编辑公钥,以验证导入的公钥的真实性**
|
||||
#gpg --edit-key someone
|
||||
someone是别人的用户ID
|
||||
出现命令提示符 >
|
||||
>fpr
|
||||
查看用户someone的公钥的指纹,之后应设法__核对指纹__,以证明真实性。如果真实,则可以签署。
|
||||
查看someone的指纹,用下面这个命令gpg --list-key
|
||||
>sign
|
||||
签署这个公钥,这样以后再使用它加密时,就不会再警告
|
||||
>check
|
||||
检查用户someone的公钥已有的签名
|
||||
出现sig! 3 sig! 1 表示已完成。输入quit,回车,再输入y保存退出
|
||||
|
||||
|
||||
====== # 私钥备份与密钥回收 ======
|
||||
|
||||
1 密钥的导出和导入:以便用来备份密钥或导入到其它机器上。这里的密钥指的是**私钥**。
|
||||
|
||||
导出
|
||||
|
||||
gpg -oa seckey.asc **--export-secret-keys** mykeyID
|
||||
|
||||
导入
|
||||
|
||||
gpg --import seckey.asc
|
||||
|
||||
2 密钥回收:当您的密钥对生成之后,您应该立即做一个__公钥回收证书__,如果您忘记了您的**私钥的口令**或者您的私钥丢失或者被盗窃,您可以发布这个证书来__声明以前的公钥不再有效__。
|
||||
|
||||
生成回收证书
|
||||
|
||||
gpg --output revoke.asc **--gen-revoke** mykeyID
|
||||
|
||||
**导入回收证书**
|
||||
|
||||
gpg --import revoke.asc
|
||||
|
||||
发送回收证书到服务器,__声明原 GPG Key 作废__
|
||||
|
||||
gpg --keyserver keyserverAddress --send mykeyID
|
||||
|
||||
====== # 列出机器中保存的所有密钥 ======
|
||||
|
||||
列出所有公钥
|
||||
|
||||
gpg -k
|
||||
|
||||
列出所有私钥
|
||||
|
||||
gpg -K
|
||||
|
||||
====== # 常规使用 ======
|
||||
下面的username均可以使用 keyid/name/Email任何一个。
|
||||
|
||||
===== 1 非对称文件加密与解密: =====
|
||||
|
||||
加密:当你**导入完好友的公钥**后,就可以__用朋友的公钥加密文件__了,
|
||||
|
||||
gpg -e -r username filename (-r 指定接收用户) 或
|
||||
gpg -e -r username -o outfilename filename #-o 可以指定输出文件名称
|
||||
|
||||
解密:上面的操作会生成 filename__.gpg__ 加密文件,之后你可以把此文件发送给好友了,对方就可以用自已的密钥来解密文件了。
|
||||
|
||||
gpg -d filename.gpg #gpg会**自动调用**本地私钥环中的私钥解密,default operation depends on the input data
|
||||
|
||||
===== 2 对称加密与解密: =====
|
||||
有时候没有得到对方的公钥,而且资料不是太重要,此时还可以使用简单的**对称加密方式**(加密及解密都使用相同的密钥/密码),加密过程中提示输出对称密钥/密码,注意:此密码是临时用的密码,不要设置和自
|
||||
|
||||
己的私钥保护密码一样,以防别人猜测及盗用!
|
||||
|
||||
加密
|
||||
|
||||
gpg **--symmetric** filename -o filename.output
|
||||
|
||||
解密
|
||||
|
||||
gpg -d filename.gpg -o filename.output
|
||||
|
||||
===== 3 对文件签名: =====
|
||||
|
||||
**数字签名 #用自己的私钥对文件签名,对方用我的公钥验证。**
|
||||
|
||||
gpg -o doc.sig__ -s__ doc #适合任何文件类型,但加密后内容是二进制。
|
||||
|
||||
其中doc是原文件,doc.sig包含了__原文件和签名,是二进制的__。这个命令会要求你输入你的私钥的密码句。
|
||||
|
||||
gpg -o doc.sig -s -er** name** doc __既签名又加密,签名用的是自己的私钥,加密使用的是对方的公钥。__
|
||||
#-s 签名选项
|
||||
#-e -r peer-name 加密选项
|
||||
|
||||
**文本签名**
|
||||
|
||||
gpg -o doc.sig --clearsign doc #加密后文件认为ASCII,所以适合文本文件。
|
||||
|
||||
这样产生的doc.sig同样包含原文件和签名,其中**签名是文本的**,而**原文件内容不变**。
|
||||
|
||||
**分离式签名**
|
||||
|
||||
gpg -o doc.sig -ab doc
|
||||
|
||||
doc.sig仅包括签名,分离式签名的意思是原文件和签名是分开的。b 表示分离式签名detach-sign
|
||||
|
||||
**验证签名**
|
||||
|
||||
gpg --verify doc.sig [doc]
|
||||
|
||||
验证之前**必须导入文件作者的公钥**,对于分离式签名,最后还要加上原文件,即后面的doc。
|
||||
|
||||
|
||||
|
||||
-- 完
|
||||
|
||||
关于 GPG 更详细的介绍请看以下两篇参考资料:
|
||||
[1]GnuPG HOWTO (中文版) http://www.gnupg.org/howtos/zh/
|
||||
[2]GPG(pgp)加解密中文完整教程 http://www.alexgao.com/2009/01/24/gpg/(PDF下载 )
|
||||
343
Zim/Utils/GPG/GPG加密和签名.txt
Normal file
@@ -0,0 +1,343 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-29T19:48:07+08:00
|
||||
|
||||
====== GPG加密和签名 ======
|
||||
Created Thursday 29 December 2011
|
||||
http://lagignition.blog.163.com/blog/static/1287300232009101082517154/
|
||||
|
||||
GnuPG全称__GNU Privacy Guard__,它是基于**公钥/私钥体系**的加密工具PGP(__Pretty Good Privacy__)的开源版本它遵循OpenPGP标准。你可以免费使用,自由传播,并可以获得它的源代码。可以用于对Email、文件及其他数据的加密与验证,确保通信数据的保密性、完整性和真实性。
|
||||
|
||||
===== 如何获得 =====
|
||||
|
||||
可以在其官方网站获得源代码和编译好的程序,当前版本是1.4.6。
|
||||
如果在Windows下使用,则安装后需要把安装目录添加进PATH环境变量以便在命令行下使用。GnuPG的__kering(密钥环)__默认保存在 C:/Documents and Settings/你的用户名/ApplicationData/gnupg目录下的话,要保存在其他地方,就得设置GNUPGHOME环境变量。具体可以看其安装目录下附带的文档。
|
||||
|
||||
===== PGP原理及规则 =====
|
||||
|
||||
在介绍GPG前,先让我们看看PGP的基本原理及应用规则。
|
||||
|
||||
PGP使用**双密匙**来加密数据。每个使用PGP加密技术的人都要创建一对密匙,一个叫做公匙,另一个叫做私匙。公匙可被广泛传播,你可以贴在自己的网页上或发到专门的__公钥管理网站__上等等。私匙属于个人信息,绝不应该泄漏给其他人。
|
||||
|
||||
公匙和私匙**相互作用**对数据进行加密及解密。被公匙加密的数据只能被私匙解密,被私匙加密的数据也只能被一个公匙解密。这样就可以实现__双重认证__。
|
||||
|
||||
例如,A要给B发信息:
|
||||
|
||||
* A不想信息被其他人看见,怎么办?
|
||||
|
||||
首先A必须通过某些途径得到B的公钥。在发送信息前,使用B的公匙对信息进行加密。这样只有B用对应的私匙才能解密收到的信息。所以就保证了信息传输的安全,这就是PGP所谓的**加密(encryption)与解密(decryption)**。
|
||||
|
||||
* B收到信息后如何确定这信息是A发的呢?
|
||||
|
||||
首先A必须通过某种途径把自己的公钥发给B。在发送信息前,A先用自己的__密钥加密信息__。B收到信息后就可以使用A的公钥来对收到的信息进行验证。这样就能确定信息来自A,这就是PGP所谓的**签名(signature)与验证(verification)**。
|
||||
|
||||
总的来说,__公钥可以用来加密和认证,私钥可以用来签名和解密。__
|
||||
|
||||
===== 如何使用GnuPG来生成自己公钥/私钥 =====
|
||||
|
||||
你首先要创建一个自己的**密钥对**,使用如下命令:
|
||||
|
||||
gpg --gen-key
|
||||
|
||||
期间会要求你输入个人信息如用户名,邮件地址,注释等,最好选有意义的。最后会让你输入passphrase(口令),这就是咱们通常意义上的密码了,解密和签名时都用得着的,按设密码的一般规则设就行了。除了那些Yes/No的问题,其他选项大可直接回车默认。
|
||||
注意:一旦有任何一个丢失,则这对密钥就需要作废。
|
||||
|
||||
这里假设我们生成了一个名为foooo的用户:
|
||||
|
||||
用户名 (注释可选)
|
||||
|
||||
foooo (nobody)
|
||||
|
||||
接着你便可以使用下面之一的命令**导出自己的公钥**了(如果本地又对各密钥对,则可以用参数__-u__来指定哪一个)
|
||||
|
||||
gpg --export foooo > foooo.pk ::导出为二进制形式,后缀名可以自己取
|
||||
gpg --armor --export foooo > foooo.pk ::导出为ASCII字符形式,可以用文本编辑工具打开查看
|
||||
|
||||
下面是文本形式公钥的一个例子
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.6 (MingW32)
|
||||
|
||||
mQGiBEV4GRURBAD9STM2AvmHRej94kjIbCfOYXZX6StxK8eU2M0d4j94KAgXe4s3
|
||||
zxV6F1AyXxZAI8jVf/wyApE7iTGQ29B+kaMf4MRwhc3F80dz7R6Zh7TkUiqCP9q/
|
||||
................................................................
|
||||
................................................................
|
||||
a8TUvPWylvqISQQYEQIACQUCRXgZHgIbDAAKCRC8O+Bl+/W+DU02AJ9Xq/5M5yiw
|
||||
2tpiz/mSOXZzo+i8RQCgjZljVuAB9an8zFrSV52fzq9GhH8=
|
||||
=N3TB
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
现在你就可以把你的公钥传到网上或发给别人了。
|
||||
|
||||
获得别人的公钥之后可以使用下面的命令把公钥__导入自己的钥匙圈,在认证时会自动调用。__
|
||||
|
||||
gpg --import someone.pk ::后缀名并不一定是pk,这里只是举例
|
||||
|
||||
===== 如何使用GnuPG来加密/解密 =====
|
||||
|
||||
你有一个文件beloved.txt要加密后发给你的GF,首先你得有GF的公钥,假设GF的**公钥的用户信息**为
|
||||
ooyymm keti@butique.com
|
||||
公钥为: ooyymm
|
||||
可以用gpg --list-keys来查看本地的所有公钥。
|
||||
|
||||
加密命令如下
|
||||
|
||||
--recipient选项指定接受者,也就是你要用__谁的公钥__来加密。在GnuPG里面指定公钥或私钥可以使用该公钥或私钥的__用户名、注释、邮件地址__等。可以只输入一部分,但要唯一,GnuPG会查找用户列表来找到所需的公钥。
|
||||
|
||||
gpg --encrypt --recipient ooyymm beloved.txt ::生成.gpg的二进制加密文件
|
||||
gpg --encrypt **--armor** --recipient ooyymm beloved.txt ::生成.asc得ASCII码签名文件
|
||||
|
||||
比如,使用邮箱地址来指定密钥:
|
||||
|
||||
gpg --encrypt --recipient keti@butique.com beloved.txt
|
||||
|
||||
当然GnuPG还可以通过其他手段来指明你要使用哪个公钥或私钥,具体请参看GnuPG的文档。
|
||||
|
||||
现在可以把加密后生成beloved.txt.gpg或beloved.txt.asc文件发给你GF吧。
|
||||
|
||||
你的GF收到文件后,必须使用自己的相应的私钥来解密,命令如下:
|
||||
|
||||
gpg --decrypt beloved.txt.gpg > beloved.txt
|
||||
gpg --__decrypt__ beloved.txt.asc > beloved.txt
|
||||
|
||||
这个过程需要输入passphrase。
|
||||
|
||||
|
||||
===== 如何使用GnuPG来签名/验证 =====
|
||||
__GPG使用公钥加密的数据可以用私钥解密,同样,使用私钥加密的数据可以用公钥解密__。
|
||||
|
||||
==== 签名过程: ====
|
||||
|
||||
1.在主机上创建密钥对
|
||||
|
||||
host # gpg --gen-key
|
||||
|
||||
按提示操作即可。操作完成后可以**查看已经创建的公钥**:
|
||||
|
||||
host # gpg --list-keys
|
||||
|
||||
2.然后使用密钥对文件进行签名,二进制签名:
|
||||
|
||||
host # gpg -s patch.tar.gz
|
||||
|
||||
创建的一个名为patch.tar.gz.gpg的文件就是签名后的包,如果想指定签名后的文件名字,可以用以下命令:
|
||||
|
||||
host # gpg -o pach.tar.gz.sig -s patch.tar.gz
|
||||
|
||||
要对对__文本文件进行明文签名__的话:
|
||||
|
||||
host # gpg --clearsign hello.txt
|
||||
|
||||
明文签名默认文件名为原文件名后加.asc,也可以使用-o 参数来指定文件名。
|
||||
|
||||
|
||||
==== 验证签名过程: ====
|
||||
签名方(host)将自己的公钥导出后发给接收方,接收方(target)将该公钥导入到本地的公钥环。
|
||||
|
||||
1.导出公钥
|
||||
|
||||
host # gpg -o pub.key --export userid
|
||||
|
||||
或者:
|
||||
|
||||
host # gpg --export userid >pub.key
|
||||
|
||||
userid是在创建密钥的时候输入的用户名。pub.key是二进制文件,如果想导出文本文件,加入-a参数即可:
|
||||
|
||||
host # gpg -a --export userid >pub.key.txt
|
||||
|
||||
2.导入公钥
|
||||
target # gpg --import pub.key
|
||||
|
||||
target # gpg --import pub.key
|
||||
|
||||
target # gpg --ignore-time-conflict --improt pub.key
|
||||
|
||||
3__.验证公钥__
|
||||
|
||||
**target** # gpg --edit-key userid
|
||||
|
||||
>fpr
|
||||
|
||||
查看这个__公钥的指纹__,核对指纹来**确认这个key正确无误**。
|
||||
|
||||
>sign
|
||||
|
||||
签署
|
||||
|
||||
->trust
|
||||
|
||||
信任
|
||||
|
||||
>quit
|
||||
|
||||
退出,问保存与否输入y。
|
||||
|
||||
4.验证签名:
|
||||
|
||||
target # gpg --verify patch.tar.gz.gpg
|
||||
|
||||
忽略时间校验:
|
||||
|
||||
target # gpg --ignore-time-conflict --verify patch.tar.gz.gpg
|
||||
|
||||
会显示签名校验的结果。
|
||||
|
||||
导入key来校验看上去比较麻烦,那么还有一种更简单的方式,直接在校验的时候通过参数来指定使用哪个key文件(**必须是二进制的文件**,文本文件不可用):
|
||||
|
||||
target # gpg __--keyring pub.key__ --verify patch.tar.gz.gpg如 果连时间都懒得设(有时候是没法设),那么也可以忽略时间戳的验证:
|
||||
|
||||
target # gpg --keyring pub.key --ignore-time-conflict --verify patch.tar.gz.gpg
|
||||
|
||||
附录:签名与验证过程
|
||||
|
||||
ms1@localhost:~/Desktop/work/sign> **gpg --gen-key**
|
||||
gpg (GnuPG) 2.0.9; Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
Please select what kind of key you want:
|
||||
(1) DSA and Elgamal (default)
|
||||
(2) DSA (sign only)
|
||||
(5) RSA (sign only)
|
||||
Your selection? 1
|
||||
DSA keypair will have 1024 bits.
|
||||
ELG keys may be between 1024 and 4096 bits long.
|
||||
What keysize do you want? (2048)
|
||||
Requested keysize is 2048 bits
|
||||
Please specify how long the key should be valid.
|
||||
0 = key does not expire
|
||||
<n> = key expires in n days
|
||||
<n>w = key expires in n weeks
|
||||
<n>m = key expires in n months
|
||||
<n>y = key expires in n years
|
||||
Key is valid for? (0)
|
||||
Key does not expire at all
|
||||
Is this correct? (y/N) y
|
||||
|
||||
You need a user ID to identify your key; the software constructs the user ID
|
||||
from the Real Name, Comment and Email Address in this form:
|
||||
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
|
||||
|
||||
Real name: lagignition
|
||||
Email address: lagignition@163.com
|
||||
Comment:
|
||||
You selected this USER-ID:
|
||||
"lagignition <lagignition@163.com>"
|
||||
|
||||
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
|
||||
You need a Passphrase to protect your secret key.
|
||||
|
||||
We need to generate a lot of random bytes. It is a good idea to perform
|
||||
some other action (type on the keyboard, move the mouse, utilize the
|
||||
disks) during the prime generation; this gives the random number
|
||||
generator a better chance to gain enough entropy.
|
||||
asdfasfdasdfasdfsadfsadf
|
||||
asidpfupjxzcv
|
||||
asdfiasjdf
|
||||
wefijklasdf
|
||||
We need to generate a lot of random bytes. It is a good idea to perform
|
||||
some other action (type on the keyboard, move the mouse, utilize the
|
||||
disks) during the prime generation; this gives the random number
|
||||
generator a better chance to gain enough entropy.
|
||||
gpg: key BC123ABC marked as ultimately trusted
|
||||
public and secret key created and signed.
|
||||
|
||||
gpg: checking the trustdb
|
||||
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
|
||||
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
|
||||
pub 1024D/BC123ABC 2009-11-06
|
||||
Key fingerprint = A943 4978 4DF9 C9A5 726C 9163 7166 AAF9 BC12 3ABC
|
||||
uid lagignition <lagignition@163.com>
|
||||
sub 2048g/586310BF 2009-11-06
|
||||
|
||||
|
||||
ms1@localhost:~/Desktop/work/sign>** gpg -s -u lagignition test.txt**
|
||||
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "lagignition <lagignition@163.com>"
|
||||
1024-bit DSA key, ID BC123ABC, created 2009-11-06
|
||||
|
||||
|
||||
ms1@localhost:~/Desktop/work/sign> **gpg -o pub_lagignition.key --export lagignition**
|
||||
|
||||
|
||||
|
||||
[root@localhost sign]# **gpg --import pub_lagignition.key**
|
||||
gpg: /root/.gnupg/trustdb.gpg: trustdb created
|
||||
gpg: key BC123ABC: public key "lagignition <lagignition@163.com>" imported
|
||||
gpg: Total number processed: 1
|
||||
gpg: imported: 1
|
||||
|
||||
|
||||
[root@localhost sign]# **gpg --verify test.txt.gpg**
|
||||
gpg: Signature made Thu 05 Nov 2009 09:24:48 PM EST using DSA key ID BC123ABC
|
||||
gpg: Good signature from "lagignition <lagignition@163.com>"
|
||||
__gpg: WARNING: This key is not certified with a trusted signature! #这需要对获得的公钥的fingerprint进行核对,然后签署它有效。__
|
||||
gpg: There is **no indication** that the signature belongs to the owner.
|
||||
Primary key fingerprint: A943 4978 4DF9 C9A5 726C 9163 7166 AAF9 BC12 3ABC
|
||||
|
||||
|
||||
[root@localhost sign]# __gpg --edit-key lagignition__
|
||||
gpg (GnuPG) 1.4.5; Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This program comes with ABSOLUTELY NO WARRANTY.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions. See the file COPYING for details.
|
||||
|
||||
|
||||
pub 1024D/BC123ABC created: 2009-11-06 expires: never usage: SC
|
||||
** trust: unknown ** ** validity: unknown**
|
||||
sub 2048g/586310BF created: 2009-11-06 expires: never usage: E
|
||||
[ unknown] (1). lagignition <lagignition@163.com>
|
||||
|
||||
Command> __fpr__
|
||||
pub 1024D/BC123ABC 2009-11-06 lagignition <lagignition@163.com>
|
||||
Primary key __fingerprint__: A943 4978 4DF9 C9A5 726C 9163 7166 AAF9 BC12 3ABC
|
||||
|
||||
Command> **trust #签署导入的公钥有效**
|
||||
pub 1024D/BC123ABC created: 2009-11-06 expires: never usage: SC
|
||||
trust: unknown validity: unknown
|
||||
sub 2048g/586310BF created: 2009-11-06 expires: never usage: E
|
||||
[ unknown] (1). lagignition <lagignition@163.com>
|
||||
|
||||
Please decide how far you __trust this user__ to correctly verify other users' keys
|
||||
(by looking at passports, checking fingerprints from different sources, etc.)
|
||||
|
||||
1 = I don't know or won't say
|
||||
2 = I do NOT trust
|
||||
3 = I trust marginally
|
||||
4 = I trust fully
|
||||
5 = I trust ultimately
|
||||
m = back to the main menu
|
||||
|
||||
Your decision? 5
|
||||
Do you really want to **set this key to ultimate trust**? (y/N) y
|
||||
|
||||
pub 1024D/BC123ABC created: 2009-11-06 expires: never usage: SC
|
||||
__ trust: ultimate__ validity: unknown
|
||||
sub 2048g/586310BF created: 2009-11-06 expires: never usage: E
|
||||
[ unknown] (1). lagignition <lagignition@163.com>
|
||||
Please note that the shown key validity is not necessarily correct
|
||||
unless you restart the program.
|
||||
|
||||
Command> quit
|
||||
[root@localhost sign]#** gpg --verify test.txt.gpg #没有警告了!**
|
||||
gpg: Signature made Thu 05 Nov 2009 09:24:48 PM EST using DSA key ID BC123ABC
|
||||
gpg: checking the trustdb
|
||||
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
|
||||
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
|
||||
gpg: Good signature from "lagignition <lagignition@163.com>"
|
||||
[root@localhost sign]# echo $?
|
||||
0
|
||||
|
||||
[root@localhost sign]# gpg --verify __-u lagignition__ test.txt.gpg
|
||||
gpg: Signature made Thu 05 Nov 2009 09:24:48 PM EST using DSA key ID BC123ABC
|
||||
gpg: Good signature from "lagignition <lagignition@163.com>"
|
||||
|
||||
|
||||
[root@localhost sign]# gpg -o test.txt test.txt.gpg
|
||||
gpg: Signature made Thu 05 Nov 2009 09:24:48 PM EST using DSA key ID BC123ABC
|
||||
gpg: Good signature from "lagignition <lagignition@163.com>"
|
||||
|
||||
Reference:
|
||||
http://bbs.wmzhe.com/redirect.php?tid=264&goto=lastpost
|
||||
51
Zim/Utils/GPG/gpg加密--数字签名.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-29T19:46:39+08:00
|
||||
|
||||
====== gpg加密--数字签名 ======
|
||||
Created Thursday 29 December 2011
|
||||
http://hi.baidu.com/aprilus/blog/item/0b31fbaeb2d3edc07cd92a47.html
|
||||
|
||||
加密:公钥加密,私钥解密[数据保密性]
|
||||
数字签名:私钥加密,公钥解密[身份认证][数据完整性][不可抵赖性]
|
||||
|
||||
生成密钥:
|
||||
$ gpg --gen-key
|
||||
--homedir 指定密钥存放的位置
|
||||
查看密钥:
|
||||
--list-keys
|
||||
--fingerprint
|
||||
--list-public-keys
|
||||
--list-secret-keys
|
||||
修改密钥:
|
||||
$ gpg --edit-key 标识名
|
||||
|
||||
导出公钥:
|
||||
$ gpg --export 标识名 > 生成文件名 ::导出为二进制形式
|
||||
$ gpg --export --armor 标识名 > 生成文件名 ::导出为ASCII字符形式
|
||||
导出私钥:
|
||||
$ gpg --export-secret-key 标识名 > 生成文件名 ::导出为二进制形式
|
||||
$ gpg --export-secret-key --armor 标识名 > 生成文件名 ::导出为ASCII字符形式
|
||||
导入密钥:
|
||||
$ gpg --import 密钥文件
|
||||
|
||||
加密:
|
||||
$ gpg --encrypt --recipient 标识名 欲加密文件 ::生成gpg后缀的二进制加密文件
|
||||
$ gpg --encrypt --armor --recipient 标识名 欲加密文件 ::生成asc后缀的ASCII加密文件
|
||||
解密:
|
||||
$ gpg --decrypt 已加密文件名 > 生成文件名
|
||||
|
||||
签名:
|
||||
$ gpg --local-user 标识名 --sign 欲签名文件 ::生成gpg后缀的二进制签名文件
|
||||
$ gpg --local-user 标识名 --sign --armor 欲签名文件 ::生成asc后缀的ASCII签名文件
|
||||
验证:
|
||||
$ gpg --verify 签名文件 ::只验证
|
||||
$ gpg --decrypt 签名文件 > 生成文件名 ::验证并还原信息
|
||||
|
||||
此外还有以下两种签名方式:
|
||||
一种主要用于文本,签名时将签名信息附在文本内容的后面,验证时只要把该文件做参数就行了。
|
||||
$ gpg --clearsign 欲签名文件
|
||||
|
||||
另一种是生成单独的签名文件。
|
||||
$ gpg --detach-sign 欲签名文件 ::生成sig后缀的二进制签名文件
|
||||
$ gpg --detach-sign --armor 欲签名文件 ::生成asc后缀的ASCII签名文件
|
||||
250
Zim/Utils/GPG/如何应用GPG加密使您的信息安全保障无忧.txt
Normal file
@@ -0,0 +1,250 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-29T20:11:17+08:00
|
||||
|
||||
====== 如何应用GPG加密使您的信息安全保障无忧 ======
|
||||
Created Thursday 29 December 2011
|
||||
|
||||
http://xjsunjie.blog.51cto.com/999372/656687
|
||||
|
||||
GPG作为一个开源并且免费的__加密和数字签名__软件已经存在多年。它不但可以为企业、个人之间的重要信息提供加密保护,还可以为出版的软件、内核等电子产品进行数字签名,防止产品被篡改,最大程度地保障信息安全。
|
||||
|
||||
加密和数字签名作为保护信息机密性、完整性和不可抵赖性的重要手段在各种信息通信场合得到广泛的应用。目前,已有不少商业加密和数字签名产品,比如**商业软件PGP**(Pretty Good Privacy)。
|
||||
|
||||
另外,在开放源代码库中也有一些免费的加密和数字签名软件,其中最被认可的是GPG(GNU Privacy Guard)。GPG是一个完全免费、源代码公开,并且与PGP完全兼容的软件产品。今天,GPG已经拥有众多的企业和个人用户。
|
||||
|
||||
在我国,由于信息安全及隐私保护意识还比较薄弱,PGP或GPG在商业和个人用户中的使用并不普遍。随着信息安全及隐私带来的问题甚至诉讼的增加,更多企业和个人开始把眼光投向安全问题的解决。
|
||||
|
||||
但是,由于非专业用户对签名和加密等概念的畏难情绪,GPG的应用还多局限于IT技术人员。本文将对Linux环境下如何应用GPG进行讲解,为企业和个人用户应用GPG提供帮助。
|
||||
|
||||
===== 建立GPG环境 =====
|
||||
GPG软件作为用于加密和数字签名的开放源码工具,许多Linux发行版本都自带了该软件。在默认安装的情况下,gpg会作为一个基本命令事先安装好。
|
||||
如果选用的Linux发行版默认没有安装GPG,可以通过tar包或RPM包进行安装,可从http://www.gnupg.org/download/下载安装包。安装过程比较简单,这里省略了。
|
||||
|
||||
判断是否安装有GPG的方法也很简单。直接在命令行下输入“gpg -h”命令,如果系统已经安装有GPG,就会显示关于GPG用法的信息。
|
||||
确定Linux系统中已经安装了GPG后,就可以开始下面加密和签名的工作了。
|
||||
|
||||
===== 生成密钥 =====
|
||||
|
||||
用户应用GPG,首先要有一对自己的密钥。所以,第一步就是产生一对密钥。gpg命令通过大量参数提供所需要的几乎所有操作。其中,参数“-gen-key”就是用来产生一对密钥的。在安装了GPG的Linux系统上可以运行以下命令:
|
||||
|
||||
#gpg --gen-key
|
||||
|
||||
如果想对产生密钥的操作进行一些个性化设置,还可以加上其它参数。比如,要指定生成密钥存放的位置,可以运行以下命令:
|
||||
|
||||
#gpg --gen-key --homedir /mygnupg
|
||||
|
||||
命令开始运行后,首先,会看到版本和路径信息如下:
|
||||
gpg (GnuPG) 1.2.1; Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
This program comes with ABSOLUTELY NO WARRANTY.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions. See the file COPYING for details.
|
||||
gpg: /home/terry/.gnupg: directory created
|
||||
gpg: new configuration file `/home/terry/.gnupg/gpg.conf' created
|
||||
gpg: keyblock resource `/home/terry/.gnupg/secring.gpg': file open error
|
||||
gpg: keyring `/home/terry/.gnupg/pubring.gpg' created
|
||||
随后需要回答一系列问题,以帮助产生一对密钥。首先遇到的问题是要求选择密钥使用的算法:
|
||||
Please select what kind of key you want:
|
||||
(1) DSA and ElGamal (default)
|
||||
(2) DSA (sign only)
|
||||
(5) RSA (sign only)
|
||||
Your selection? 1
|
||||
其中,__DSA是数字签名算法__,RSA和ElGamal是两种不同原理的非对称密钥算法。通常可以选择“1”,这样生成的密钥可以__同时用作签名和加密__两种用途。
|
||||
接着,会要求选择密钥的长度:
|
||||
DSA keypair will have 1024 bits.
|
||||
About to generate a new ELG-E keypair.
|
||||
minimum keysize is 768 bits
|
||||
default keysize is 1024 bits
|
||||
highest suggested keysize is 2048 bits
|
||||
What keysize do you want? (1024) 2048
|
||||
Requested keysize is 2048 bits
|
||||
这里的密钥长度有768、1024和2048位三种。显然,密钥越长越安全,但太长又会影响使用的速度。所以,可以根据不同的需要选择适合的长度。笔者的应用更重视安全性,所以选择了最长的2048位密钥。
|
||||
另外,还需要设定密钥过期的时间:
|
||||
Please specify how long the key should be valid.
|
||||
0 = key does not expire
|
||||
= key expires in n days
|
||||
w = key expires in n weeks
|
||||
m = key expires in n months
|
||||
y = key expires in n years
|
||||
Key is valid for? (0) 1y
|
||||
Key expires at Sat 10 Sep 2005 01:48:07 PM CST
|
||||
Is this correct (y/n)? y
|
||||
原则上,密钥使用的频率越高,密钥有效的时间越长,被攻击的可能性就越大。所以,要根据应用的实际情况综合考虑,确定一个适当的时间长度。需要注意的是,密钥要定期更换,建议绝对不要永远使用同一对密钥。
|
||||
最后,需要输入一些个人信息,包括真实姓名、电子邮件地址等,__用来识别密钥__,最好是如实填写。比如:
|
||||
Real name: Terry Yu
|
||||
Email address: terry@mykms.org
|
||||
Comment: for test
|
||||
You selected this USER-ID:
|
||||
"Terry Yu (for test) "
|
||||
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
|
||||
然后,必须输入一个密码。密码用来保护密钥,没有这个密码,任何人都不能看到密钥本身的内容。密码是在密钥文件泄露后惟一的保密措施,它的最大敌人是暴力破解和字典攻击。所以,一定要选择一个强壮的密码,来有效地对抗这些攻击。
|
||||
密码确定以后,系统开始运算:
|
||||
We need to generate a lot of random bytes.
|
||||
It is a good idea to perform some other action
|
||||
(type on the keyboard, move the mouse, utilize the disks)
|
||||
during the prime generation;
|
||||
this gives the random number generator a better
|
||||
chance to gain enough entropy.
|
||||
..+++++.+++++.+++++.+++++..++++++++++.++++++++++++++
|
||||
这时需要随便地敲击键盘或是移动鼠标,以产生一些随机数,协助密钥的顺利生成。注意,如果没有以上动作,很可能最终不能产生密钥。
|
||||
系统运算完成后,会出现类似以下的信息:
|
||||
gpg: /home/terry/.gnupg/trustdb.gpg: trustdb created
|
||||
public and secret key created and signed.
|
||||
key marked as ultimately trusted.
|
||||
pub 1024D/6AE573B5 2004-09-29 Terry Yu (for test)
|
||||
Key fingerprint = 0D58 408E 344F BB7B AB95 D000 82B7 8324 6AE5 73B5
|
||||
sub 2048g/94BF182C 2004-09-29 [expires: 2005-09-29]
|
||||
pub 1024D/7234E374 2004-09-10 Terry Yu (for test)
|
||||
Key fingerprint = A58F D71A 28BA 499D 805B 588E 82FB CD0F 7234 E374
|
||||
sub 2048g/4907EA0A 2004-09-10 [expires: 2005-09-10]
|
||||
以上信息表示已经成功地为“Terry
|
||||
Yu”生成并签名了一对密钥,密钥过期时间为“2005-09-10”。在生成密钥的同时,默认用户目录的__.gnupg目录__中也存放了与该用户相关的
|
||||
GPG配置及密钥存储文件。这些文件控制了用户的GPG环境,用户不能直接修改这些文件,所有改动都将通过“gpg”命令实现。
|
||||
|
||||
===== 查看密钥 =====
|
||||
密匙生成后,可以随时用以下命令查看。
|
||||
查看所有密钥:
|
||||
#gpg -list-key
|
||||
查看所有公钥:
|
||||
gpg -list-public-key
|
||||
查看所有私钥:
|
||||
gpg -list-secret-key
|
||||
列出所有签名:
|
||||
gpg -list-sig
|
||||
|
||||
===== 导出公钥 =====
|
||||
在非对称加密体系中,**私钥是由用户保管,而公钥是对外公开**的。用户在生成密钥对后,需要把其中的公钥导出到一个文件中,然后将其分发给其它用户。
|
||||
导出公钥的方法很简单,通过gpg命令的“-export”参数就可完成。为了使导出文件是ASCⅡ编码的,还需要加上参数“-a”。比如,导出Terry Yu ASCⅡ编码的公钥文件,可以使用以下命令:
|
||||
#gpg --export -a terry@mykms.org > terry.asc
|
||||
该命令最终生成ASCⅡ编码的公钥文件terry.asc
|
||||
|
||||
|
||||
===== 分发公钥 =====
|
||||
这个包含公钥信息的文件需要对外分发,可以通过各种方式将terry.acs文件分发给所有与用户有信息通信需求的人。
|
||||
最简单的分发方式是,将该文件__放到互联网上供人下载__。这种方式需要注意的问题是,所发布公钥文件的网站一定要是一个可以信赖的站点。实际应用中,类似的做法很普遍。比如,Red Hat的公钥就是在它的官方网站上发布的,任何人都可以下载获得,并用来验证Red Hat所发布软件的签名的正确性。
|
||||
|
||||
===== 导入公钥 =====
|
||||
作为用户,也会收到别人的GPG公钥,它们可能来自网站、电子邮件、FTP和目录服务等,__只要信任其来源__,就可以将其导入自己的GPG环境,之后才可以与相应的人员进行基于GPG的各种应用。导入公钥的过程可以分为以下三步:
|
||||
|
||||
=== 1.导入 ===
|
||||
比如,Terry收到朋友Brian的公钥文件brian.gpg,可以使用以下命令导入文件:
|
||||
#gpg --import terry.gpg
|
||||
|
||||
=== 2.核对“指纹” ===
|
||||
公钥是可以伪造的。James可以伪造一个Brian的公钥,然后想办法让Terry得到。如果Terry对收到的公钥不加验证,那么他发给Brian的加密邮件就可能被James解密。GPG的架构中__并没有一个PKI这样的证书管理系统__,__GPG的公钥信任是通过“Truth Web”实现__的。
|
||||
|
||||
生成Terry__公钥的“指纹”__:
|
||||
#gpg --fingerprint terry@mykms.org
|
||||
pub 1024D/7234E374 2004-09-10 Terry
|
||||
Yu (for test)
|
||||
Key fingerprint = A58F D71A 28BA
|
||||
499D 805B 588E 82FB CD0F 7234 E374
|
||||
sub 2048g/4907EA0A 2004-09-10 [expires: 2005-09-10]
|
||||
这个“指纹”是惟一的。可以通过与对方__核对“指纹”是否一致__,来确定这个公钥是否可信和合法。
|
||||
|
||||
=== 3.签名 ===
|
||||
在成功导入,并确定这个公钥是可以相任之后,要立即__对这个公钥进行签名__。这样,就可以验证来自对方邮件的真实性了。
|
||||
对公钥进行签名可以使用如下命令:
|
||||
#gpg __--sign-key__ brian@mykms.org
|
||||
或者
|
||||
#gpg__ --edit-key__ name
|
||||
#command > sign
|
||||
检查对方邮件,比如Brian的签名:
|
||||
#gpg --check-sigs brian@mykms.org
|
||||
现在,有了Brian签名的公钥,通过这个公钥就可以和Brain进行非对称加密通信了。
|
||||
|
||||
|
||||
===== 应用GPG =====
|
||||
GPG使用的是非对称的密钥体系,用户拥有一对密钥,包括一个公钥和一个私钥。公钥对外公布,私钥则由自己保存。__使用公钥加密的数据可以用私钥解密,同样,使用私钥加密的数据可以用公钥解密__。
|
||||
|
||||
非对称的密钥可以用来加密和做数字签名。当用户关心信息**保密性**时,使用加密功能;当用户关注**信息完整性及不可抵赖性**时,使用数字签名功能;当用户需要同时关注信息的机密性、完整性及不可抵赖性时,可以将加密和数学签名__混合使用__。简单了解这些密码学概念后,就可以开始真正的应用实践了。
|
||||
|
||||
==== 对文件进行加密和数字签名 ====
|
||||
KDE中提供了图形化的加密操作方法。比如,在KDE中对一个文件加密,只需在KDE文件管理器Konqueror中选中该文件,单击右键选择“Actions”中的“Encrypt File”就可以加密文件。加密后的文件以__.asc__结尾。
|
||||
对于图形方式的加密操作不多做介绍,下面将重点放在命令行操作方式上,介绍命令行下的各种文件加密和签名的操作方法。
|
||||
|
||||
1.对文件进行数字签名
|
||||
#gpg --clearsign policy.txt
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "test (test) "
|
||||
1024-bit DSA key, ID ADD93830, created 2004-07-01
|
||||
运行以上命令,生成一个名为report.txt.asc的文件,该文件中除了原文件信息外还包含数字签名信息。
|
||||
|
||||
2.验证文件的数字签名
|
||||
#gpg --verify policy.txt.asc
|
||||
gpg: Signature made 2004年11月04日 星期四 15时58分07秒 UTC using DSA key ID ADD93830
|
||||
gpg: Good signature from "test (test) "
|
||||
以上命令运行的结果显示该签名是正确的。
|
||||
|
||||
3.用指定的公钥对文件加密
|
||||
#gpg --encrypt -r terry@mykms.org report.txt
|
||||
gpg: checking the trustdb
|
||||
gpg: checking at depth 0 signed=0 ot(-/q/n/m/f/u)=0/0/0/0/0/1
|
||||
gpg: next trustdb check due at 2005-09-10
|
||||
运行以上命令,使用对方的公钥加密report.txt文件,生成加密文件report.txt.gpg。如果使用编辑软件打开该加密文件,会发现它包含的是一些不可理解的字符和乱码。
|
||||
|
||||
4.用私钥对加密文件解密
|
||||
#gpg --decrypt report.txt.gpg >report.txt
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "test1 (unclassfication) "
|
||||
2048-bit ELG-E key, ID 33735683, created 2004-09-29
|
||||
(main key ID 79EB3D97)
|
||||
gpg: encrypted with 2048-bit ELG-E key, ID 33735683,
|
||||
created 2004-09-29
|
||||
"test1 (unclassfication) "
|
||||
以上命令要求输入对应私钥的保护口令才能成功解密,解密后的文件内容被输出到report.txt文件中。
|
||||
|
||||
5.用公钥同时进行文件签名和加密
|
||||
#gpg -se -r test@yahoo.com.cn report.txt
|
||||
You need a passphrase to unlock the secret key for
|
||||
user: "test (test) "
|
||||
1024-bit DSA key, ID ADD93830, created 2004-07-01
|
||||
以上命令要求输入对应私钥的保护口令,输入正确的口令后,签名和加密成功完成。
|
||||
这些都是应用GPG签名和加密文件的一些常用命令,更详细的用法可以参考GPG的帮助文件。
|
||||
|
||||
==== 对电子邮件进行加密和数字签名 ====
|
||||
实际上,GPG应用最多的地方是在电子邮件的加密和数字签名上。许多__电子邮件客户端软件__都支持PGP/GPG方式的加密及数字签名。这里以Kmail为例,介绍如何设置Kmail,并利用Kmail发送加密及数字签名的电子邮件。
|
||||
Kmail
|
||||
是KDE环境中的电子邮件客户端,类似于Windows下的Outlook
|
||||
Express。在选单中选择“Settings→Configure-Kmail→Identites”,选定一个身份,单击“Modify”进行编
|
||||
辑。选择其中的“Advanced”标签页,可以看到类似图2的界面。
|
||||
|
||||
其中,“OpenPGP Key”项是该身份所对应的PGP或GPG密钥,可以单击“Change”按钮从GPG环境中选择对应的密钥对。
|
||||
保存后,GPG的设置完成。试写一封邮件,如图3所示。图中工具栏中凹下去的“钢笔尖”图标表示此邮件使用了数字签名,紧靠旁边的锁形图标表示加密,如果两个图标都凹下去则表示同时使用了加密和数字签名。
|
||||
|
||||
图3 使用数字签名的电子邮件
|
||||
发送邮件时,Kmail会要求给出对应密钥的保护口令,如图4所示。
|
||||
|
||||
图4 要求输入密钥保护口令
|
||||
正确输入保护口令后,会弹出一个确认窗口,如图5。
|
||||
|
||||
图5 确认窗口
|
||||
确认内容无误后,单击“OK”按钮,一封带有数字签名的电子邮件就成功发出。发送加密邮件,以及发送同时加密和数字签名的邮件,方法都是类似的。
|
||||
|
||||
==== 软件包签名验证 ====
|
||||
对于Red Hat等Linux发行商来说,他们常常会利用GPG对**发布的软件包进行签名**。用户可以通过验证软件包的签名来确保得到的软件包没有损坏,或者是被他人动过手脚。
|
||||
|
||||
验证一个下载软件包的GPG签名可以按照以下步骤来进行:
|
||||
1.从网上下载或其它方式得到软件发行商的公钥,并将其导入自己的GPG环境中。
|
||||
2.通过对比“电子指纹”来__确认公钥__,并对此公钥进行签名。
|
||||
3.使用以下命令来验证软件包的GPG签名:
|
||||
#__gpg --verify singaturefile.tar.gz taballpackage.gz__
|
||||
如果该软件是RPM格式的,还可以使用如下命令来验证:
|
||||
#rpm -Kv your.rpm
|
||||
|
||||
===== 密钥管理 =====
|
||||
前面介绍了GPG在加密和签名两方面的应用,在应用过程中用户要认真地对待密钥管理问题。GPG的密钥采用的是信任机制,并没有一个中心的PKI可以帮助发布和验证GPG用户的公钥。为了防止公钥欺骗,保证公钥的不可否认性(Non-repudiation),需要有一种机制来进行管理。下面是一些有益的建议,可供参考。
|
||||
|
||||
◆ 备份好私钥
|
||||
一旦私钥丢失或损坏,则无法打开以前加密的文件。并且,即使知道私钥被他人滥用,也无法使自己的公钥过期。有了私钥的备份,就能有效地回避此类风险。
|
||||
◆ 建立有过期保护的公钥机制
|
||||
万一私钥丢失不能人工收回公钥时,公钥也可以在预定时间后自动过期。
|
||||
◆ 为私钥加上强口令保护
|
||||
这样,即使私钥文件泄漏,还有口令保护。保护口令一定要有足够的复杂度,才能有效地对抗暴力破解。
|
||||
◆ 多重机制
|
||||
在紧急情况下恢复密钥要有多重控制。
|
||||
◆ 使用版本控制软件
|
||||
使用版本控制软件来收集和维护自己的公钥库。版本控制软件可以有效地记录历史变更情况,保证公钥库的有条不紊。
|
||||
|
||||
===== 小结 =====
|
||||
GPG作为一个开源并且免费的加密和数字签名软件已经存在多年。它不但可以为企业、个人之间的重要信息提供加密保护,还可以为出版的软件、内核等电子产品进行数字签名,防止产品被篡改,最大程度地保障信息安全。对于Linux用户来说,对信息安全的要求相对更高,GPG更值得在Linux用户中推广和应用。
|
||||
7
Zim/Utils/Graphviz.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-02-19T22:02:41+08:00
|
||||
|
||||
====== Graphviz ======
|
||||
Created Sunday 19 February 2012
|
||||
|
||||
89
Zim/Utils/Graphviz/Graphviz介绍.txt
Normal file
@@ -0,0 +1,89 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-02-19T22:02:53+08:00
|
||||
|
||||
====== Graphviz介绍 ======
|
||||
Created Sunday 19 February 2012
|
||||
http://abruzzi.iteye.com/blog/429042
|
||||
|
||||
graphviz是贝尔实验室几个计算机牛人设计的一个__开源的图表(计算机科学中数据结构中的图)可视化项目__,主要用C语言实现,主要实现了一些__图布局算法__。通过这些算法,可以将图中的节点在画布上比较均匀的分布,缩短节点之间的边长,并且尽量的减少边的交叉。
|
||||
|
||||
|
||||
graphviz提供命令式的绘图方式,它提供__一个dot语言__用来编写绘图脚本,然后对这个脚本进行解析,分析出其中的**定点,边以及子图**,然后根据__属性__进行绘制。具体的可以看一个例子,这个例子来自官方的文档。
|
||||
|
||||
|
||||
Dot代码 收藏代码
|
||||
|
||||
digraph G {
|
||||
main -> parse -> execute;
|
||||
main -> init;
|
||||
main -> cleanup;
|
||||
execute -> make_string;
|
||||
execute -> printf
|
||||
init -> make_string;
|
||||
main -> printf;
|
||||
execute -> compare;
|
||||
}
|
||||
|
||||
|
||||
digraph指定该图是一个有向图(directed graph),->表示一条边,main,parse,execute等是顶点,运行出来的效果很好看,如下图:
|
||||
|
||||
|
||||
需要注意的是,我在这个dot脚本中__没有指定任何的关于图的位置的信息__,布局器会自动的根据图形的类型进行布局,并最终展现出来。
|
||||
|
||||
再来看一个比较复杂,并且是程序员经常使用的功能,数据结构图:
|
||||
|
||||
digraph g {
|
||||
node [shape = record,height=.1];
|
||||
node0[label = "<f0> |<f1> G|<f2> "];
|
||||
node1[label = "<f0> |<f1> E|<f2> "];
|
||||
node2[label = "<f0> |<f1> B|<f2> "];
|
||||
node3[label = "<f0> |<f1> F|<f2> "];
|
||||
node4[label = "<f0> |<f1> R|<f2> "];
|
||||
node5[label = "<f0> |<f1> H|<f2> "];
|
||||
node6[label = "<f0> |<f1> Y|<f2> "];
|
||||
node7[label = "<f0> |<f1> A|<f2> "];
|
||||
node8[label = "<f0> |<f1> C|<f2> "];
|
||||
"node0":f2 -> "node4":f1;
|
||||
"node0":f0 -> "node1":f1;
|
||||
"node1":f0 -> "node2":f1;
|
||||
"node1":f2 -> "node3":f1;
|
||||
"node2":f2 -> "node8":f1;
|
||||
"node2":f0 -> "node7":f1;
|
||||
"node4":f2 -> "node6":f1;
|
||||
"node4":f0 -> "node5":f1;
|
||||
}
|
||||
|
||||
|
||||
运行后的效果如下图所示:
|
||||
|
||||
|
||||
不知道其他的程序员怎样,反正我对命令行情有独钟,比较喜欢这一类的工具。最早接触的计算机系统正是一个没有图形系统的BSD,由此对命令行的,没有界面的程序都特别感兴趣。
|
||||
|
||||
===== 相关的想法 =====
|
||||
|
||||
自从使用了graphviz以后,一直想着把这个好东西移植到java下来,大概的思想跟graphviz类似:
|
||||
|
||||
* 解析dot脚本,生成图的对象,这个图中包括**节点,边以及子图**等对象,这些对象上都绑定着相应的**属性**
|
||||
* 将解析出来的图对象发送给layout engine进行处理,**layout engine**可以选择__布局策略__,比如流布局等
|
||||
* 从layout engine中得到布局后的图对象,并交给**image engine**处理,得到最终结果,负责展示或者保存等
|
||||
|
||||
dot 的语法定义比较简单,我已经用javacc构造了一个dot的分析器,现在可以从dot文件中构建出图对象出来,不过还需要进一步完善,可以看看这个BNF定义:
|
||||
|
||||
graph -> [strict] (digraph|graph) id '{' stmt-list '}'
|
||||
stmt-list -> [stmt [';'] [stmt-list] ]
|
||||
stmt -> attr-stmt | node-stmt | edge-stmt | subgraph | id '=' id
|
||||
attr-stmt -> (graph | node | edge) attr-list
|
||||
attr-list -> '[' [a-list] ']' [attr-list]
|
||||
a-list -> id '=' id [','][a-list]
|
||||
node-stmt -> node-id [attr-list]
|
||||
node-id -> id [port]
|
||||
port -> port-location [port-angle] | port-angle [port-location]
|
||||
port-location -> ':' id | ':' '(' id ',' id ')'
|
||||
port-angle ->'@' id
|
||||
edge-stmt -> (node-id | subgraph) edgeRHS [attr-list]
|
||||
edgeRHS -> edgeop (node-id | subgraph) [edgeRHS]
|
||||
subgraph -> [subgraph id] '{' stmt-list '}' | subgraph id
|
||||
|
||||
|
||||
当然graphviz的功能不至于此,它提供一个lib,可以用来__将绘图引擎嵌入在自己的应用中__。这是一个很有意义的事,我们可以不必掌握布局部分的复杂算法,把精力放在业务逻辑部分,将最后的图对象交给这个引擎来处理即可。当然,如果你正好和我一样,想了解其神奇的布局算法,不妨翻翻它的源码,欢迎交流之至。
|
||||
234
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用.txt
Normal file
@@ -0,0 +1,234 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-02-20T16:51:57+08:00
|
||||
|
||||
====== 用 Graphviz 可视化函数调用 ======
|
||||
Created Monday 20 February 2012
|
||||
|
||||
http://www.ibm.com/developerworks/cn/linux/l-graphvis/
|
||||
|
||||
使用开源软件来简化复杂调用结构
|
||||
M. Tim Jones, 资深软件工程师, Emulex
|
||||
|
||||
简介: 花一些时间遍历一下源代码,可以向您展现__所有的函数调用过程__;但是如果函数指针非常复杂,或者代码太长且晦涩难懂,那么这个过程就可能更加困难了。本文将向您介绍如何使用开源软件和一些定制的代码来__构建一个动态的图形函数调用生成器__。
|
||||
|
||||
|
||||
发布日期: 2005 年 7 月 11 日
|
||||
级别: 初级
|
||||
访问情况 : 9243 次浏览
|
||||
评论: 0 (查看 | 添加评论 - 登录)
|
||||
平均分 5 星 共 14 个评分 平均分 (14个评分)
|
||||
为本文评分
|
||||
|
||||
可以将__以图形形式查看应用程序的调用过程__看作是一个学习经历。这样做可以帮助您__理解应用程序的内部行为__,并获得有关__程序优化方面的信息__。例如,通过对那些经常调用的函数进行优化,您就可以用最少的努力来获得最佳的性能。另外,调用跟踪还可以判断用户函数的__最大调用深度__,这可以用来对调用栈使用的内存进行有效限制(在嵌入式系统中,这是非常重要的一个考虑因素)。
|
||||
|
||||
为了捕获并显示调用图,您需要 4 个元素:**GNU 编译器工具链、Addr2line 工具、定制的中间代码和一个名为 Graphviz 的代码**。Addr2line 工具可以识别函数、给定地址的源代码行数和可执行映像。定制的中间代码是一个非常简单的工具,它可以减少对图形规范的地址跟踪。Graphviz 工具可以生成图形映像。整个过程如图 1 所示。
|
||||
{{./figure1.gif}}
|
||||
图 1. 搜集、简化和可视化跟踪路径的过程
|
||||
|
||||
===== 跟踪过程 =====
|
||||
|
||||
==== 数据搜集:捕获函数调用路径 ====
|
||||
|
||||
要收集一个函数调用的踪迹,您需要__确定每个函数在应用程序中调用的时间__。在过去,都是通过在函数的**入口处和退出处**插入一个惟一的符号来手工检测每个函数的。这个过程非常繁琐,而且很容易出错,通常需要对源代码进行大量的修改。
|
||||
|
||||
幸运的是,GNU 编译器工具链(也称为 gcc)提供了一种__自动检测应用程序中的各个函数的方法__。在执行应用程序时,就可以收集相关的分析数据。您只需要**提供两个特殊的分析函数即可**。其中一个函数在每次执行想要跟踪的函数时都会调用;而另外一个函数则在每次退出想要跟踪的函数时调用(参见清单 1)。这两个函数都是特别指定的,因此,编译器可以识别它们。
|
||||
|
||||
清单 1. GNU 的入口和出口配置函数
|
||||
|
||||
|
||||
void __cyg_profile_func_enter( void *func_address, void *call_site )
|
||||
__attribute__ ((no_instrument_function));
|
||||
void __cyg_profile_func_exit ( void *func_address, void *call_site )
|
||||
__attribute__ ((no_instrument_function));
|
||||
|
||||
|
||||
===== 避免使用特殊的检测函数 =====
|
||||
|
||||
您或许会产生疑惑,如果 gcc 就是我们需要的检测函数,那么为什么它**不检测 __cyg_* 分析函数呢**?gcc 的开发者曾思考过这个问题,他们提供了一个名为 __no_instrument_function 的函数属性__,这个函数属性可以应用于函数原型,__禁止对它们进行检测__。不要将这个函数属性应用到分析函数上,这样会导致无限递归分析循环和大量的无用数据。
|
||||
|
||||
在调用一个检测函数时,__cyg_profile_func_enter 同时也会被调用,并**以 func_address 形式传递调用的函数地址**,以及**从中调用该函数的 call_site 形式的地址**。反之,当一个函数退出时,也会调用 __cyg_profile_func_exit 函数,并传递 func_address 形式的函数地址,以及函数从中退出的真实地址,该地址的表示形式为 call_site。
|
||||
|
||||
在这些分析函数中,您可以**记录下地址对**,以供以后再进行分析使用。__要请求 gcc 所有的检测函数,每个文件都必须使用 -finstrument-functions 和 -g 选项进行编译,这样可以保留调试符号。__
|
||||
|
||||
因此,现在您就可以为 gcc 提供一些分析函数了,这些函数可以透明地插入应用程序中的函数入口点和函数退出点。但在调用分析函数时,又应该怎样处理所提供的地址呢?您有很多选择,但是为了简便起见,可以__将这个地址简单地写入一个文件__,要注意哪个地址是函数的入口地址,哪个地址是函数的出口地址(参见清单 2)。
|
||||
|
||||
注意:在清单 2 中并没有使用调用 Callsite 信息,因为这些信息对于分析程序来说是不必要的。
|
||||
|
||||
清单 2. 分析函数
|
||||
|
||||
|
||||
void __cyg_profile_func_enter( void *this, void *callsite )
|
||||
{
|
||||
/* Function Entry Address */
|
||||
fprintf(fp, "E__%p__\n", __(int *)this__);
|
||||
}
|
||||
void __cyg_profile_func_exit( void *this, void *callsite )
|
||||
{
|
||||
/* Function Exit Address */
|
||||
fprintf(fp, "X%p\n", (int *)this);
|
||||
}
|
||||
|
||||
|
||||
现在您可以搜集分析数据了,但是您应该**在什么地方打开或关闭您的跟踪输出文件**呢?到现在为止,还不需要为了进行分析而对源程序进行任何修改。因此,您该如何检测整个应用程序(包括 main 函数)而不用对分析数据的输出结果进行初始化呢?gcc 的开发者也考虑过这个问题,__它们为 main 函数的 constructor 函数和 destructor 函数提供了一些碰巧能够满足这个要求一些方法。__constructor 函数是在调用 main 函数之前调用的,而 destructor 函数则是在应用程序退出时调用的。
|
||||
|
||||
要创建 constructor 和 destructor 函数,则需要声明两个函数,然后**对这两个函数应用 constructor 和 destructor 函数属性**。在 constructor 函数中,会打开一个新的跟踪文件,分析数据的地址跟踪就是写入这个文件的;在 destructor 函数中,会关闭这个跟踪文件(参见清单 3)。
|
||||
|
||||
清单 3. 分析 constructor 和 destructor 函数
|
||||
|
||||
|
||||
/* Constructor and Destructor Prototypes */
|
||||
void main_constructor( void )
|
||||
__attribute__ ((no_instrument_function, **constructor**));
|
||||
void main_destructor( void )
|
||||
__attribute__ ((no_instrument_function, destructor));
|
||||
/* Output trace file pointer */
|
||||
static FILE *fp;
|
||||
void main_constructor( void )
|
||||
{
|
||||
fp = __fopen__( "trace.txt", "w" );
|
||||
if (fp == NULL) exit(-1);
|
||||
}
|
||||
void main_deconstructor( void )
|
||||
{
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
|
||||
如果编译分析函数(在 instrument.c)__并将它们与目标应用程序链接在一起__,然后再执行目标应用程序,结果会生成**一个应用程序的调用追踪**,追踪记录被写入 trace.txt 文件。跟踪文件与调用的应用程序处于相同的目录中。最终结果是,您可能会得到一个其中满是地址的非常大的文件。为了能够让这些数据更有意义,您可以使用一个不太出名的叫做 Addr2line 的 GNU 工具。
|
||||
|
||||
|
||||
===== 使用 Addr2line 将函数地址解析为函数名 =====
|
||||
Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个__可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具__。这种功能对于将跟踪地址转换成更有意义的内容来说简直是太棒了。
|
||||
|
||||
要了解这个过程是怎样工作的,我们可以试验一个简单的交互式的例子。(我直接从 shell 中进行操作,因为这是最简单地展示这个过程的方法,如清单 4 所示。)这个示例 C 文件(test.c)是通过 cat 一个简单的应用程序实现的(也就是说,将标准输出的文本重定向到一个文件中)。然后使用 gcc 来编译这个文件,它会传递一些特殊的选项。首先,**要(使用 -Wl 选项)通知链接器生成一个映像文件**,并(使用 -g 选项)通知编译器__生成调试符号__。最终生成可执行文件 test。得到新的可执行应用程序之后,您就可以使用 grep 工具在映像文件中查找 main 来寻找它的地址了。使用这个地址和 Addr2line 工具,就可以判断出函数名(main)、源文件(/home/mtj/test/test.c)以及它在源文件中的行号(4)。
|
||||
|
||||
在调用 Addr2line 工具时,要使用 -e 选项来指定可执行映像是 test。通过使用 -f 选项,可以告诉工具输出函数名。
|
||||
|
||||
清单 4. addr2line 的一个交互式例子
|
||||
|
||||
$ cat >> test.c
|
||||
#include <stdio.h>
|
||||
int main()
|
||||
{
|
||||
printf("Hello World\n");
|
||||
return 0;
|
||||
}
|
||||
<ctld-d>
|
||||
$ gcc -Wl,__-Map=test.map__ -g -o test test.c //也可以不用指定-Wl,-Map参数
|
||||
$ grep **main** test.map //__使用nm命令查找所有的符号地址和名称。__
|
||||
0x08048258 __libc_start_main@@GLIBC_2.0
|
||||
0x08048258 main
|
||||
$ __addr2line 0x08048258 -e test -f__
|
||||
main
|
||||
/home/mtj/test/test.c:4
|
||||
$
|
||||
|
||||
=== Addr2line 和调试器 ===
|
||||
|
||||
Addr2line 工具提供了**基本的符号调试信息**,不过 GNU Debugger (GDB)使用的是其他一些内部方法。
|
||||
|
||||
|
||||
|
||||
===== 精简函数跟踪数据 =====
|
||||
|
||||
现在您有了一个可以搜集函数函数地址的追踪数据的方法,还可以使用 Addr2line 工具将地址转换为函数名。然而,从应用程序中产生大量的跟踪数据之后,如何__对这些数据进行精简,从而使其更有意义呢__?这就是使用一些定制的中间代码在开源工具之间建立联系的地方。本文提供了这个工具(Pvtrace)的带有注释的完整代码,包括如何编译和使用该工具的一些说明。(有关的更多信息,请参阅 下载 一节。)
|
||||
|
||||
回想一下图 1 中的内容,在执行设置了检测函数的应用程序时,会创建一个名为 trace.txt 的文本文件。这个人们可以读取的文件中包含了一系列地址信息 —— 每行一个地址,每行都有一个前缀字符。**如果前缀是 E,那么这个地址就是一个函数的入口地址(也就是说,您正在调用这个函数)。如果前缀是一个 X 字符,那么这个地址就是一个出口地址**(也就是说,您正在从这个函数中退出)。
|
||||
|
||||
因此,如果在跟踪文件中有一个入口地址(A)紧跟着另外一个入口地址(B),那么您就可以推断是 A 调用了 B。如果一个入口地址(A)后面跟着一个出口地址(A),那么就说明这个函数(A)被调用后就直接返回了。当涉及大量的调用链时,就很难分析究竟是谁调用了谁,因此,__一种简单的解决方案是维护一个整个地址的堆栈__。每次在跟踪文件中碰到一个入口地址时,就将其压入堆栈。栈顶的地址就代表最后一次被调用的函数(也就是当前的活动函数)。如果后面紧接着是另外一个入口地址,这说明堆栈中的地址调用了这个刚从跟踪文件处读出的地址。在碰到退出函数时,当前的活动函数就会返回,并释放栈顶元素。这会将上下文返到回前一个函数,由此,就可以产生正确的__调用链过程__。
|
||||
|
||||
图 2 介绍了这个概念,以及精简数据的方法。在分析跟踪文件中的调用链时,会__构建一个连通矩阵__,用来**表示哪个函数调用了其他哪些函数**。这个矩阵的行表示调用函数的地址,列表示被调用的地址。对于每个调用对来说,行与列的__交叉点不断进行累加__(调用次数)。当处理完整个跟踪文件时,其结果是该应用程序的整个调用历史的一个非常简单的表示,其中包含了调用的次数。
|
||||
{{./figure2.gif}}
|
||||
图 2. 对跟踪数据进行处理和精简,并生成矩阵格式
|
||||
|
||||
===== 精简过程 =====
|
||||
|
||||
=== 编译并安装工具 ===
|
||||
在下载并解压 Pvtrace 工具之后,只需在子目录中输入 make 命令,就可以编译 Pvtrace 工具了。也可以使用下面的代码将这个工具安装到 /usr/local/bin 目录中:
|
||||
|
||||
$ unzip pvtrace.zip -d pvtrace
|
||||
$ cd pvtrace
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
现在我们已经构建了简化的函数连通性矩阵,接下来应该__构建图形的表示__了。让我们深入研究 Graphviz,了便理解如何从连通矩阵生成一个调用图。
|
||||
|
||||
===== 使用 Graphviz =====
|
||||
Graphviz 或 Graph Visualization 是由 AT&T 开发的一个__开源的图形可视化工具__。它提供了多种画图能力,但是我们重点关注的是它使用 Dot 语言直连图的能力。在本文中,我们将简单介绍如何使用 Dot 来创建一个图形,并展示如何将分析数据转换成 Graphviz 可以使用的规范。(请参阅 参考资料 一节,以获得有关下载这个开源软件的信息。)
|
||||
|
||||
===== Dot 使用的图形规范 =====
|
||||
|
||||
使用 Dot 语言,您可以指定三种对象:__图、节点和边__。为了让您理解这些对象的含义,我们将构建一个例子来展示这些元素的用法。
|
||||
|
||||
清单 5 给出了一个简单的__定向图__(directed graph),其中包含 3 个节点。第一行声明这个图为 G,并且声明了该图的类型(digraph)。接下来的三行代码用于创建该图的节点,这些节点分别名为 node1、node2 和 node3。节点是在它们的名字出现在图规范中时创建的。边是在在两个节点使用边操作(->)连接在一起时创建的,如第 6 行到第 8 行所示。我还对边使用了一个可选的属性 label,用它来表示边在图中的名称。最后,在第 9 行完成对该图规范的定义。
|
||||
|
||||
清单 5. 使用 Dot 符号表示的示例图(test.dot)
|
||||
|
||||
|
||||
1: digraph G {
|
||||
2: node1;
|
||||
3: node2;
|
||||
4: node3;
|
||||
5:
|
||||
6: node1 -> node2 [label="edge_1_2"];
|
||||
7: node1 -> node3 [label="edge_1_3"];
|
||||
8: node2 -> node3 [label="edge_2_3"];
|
||||
9: }
|
||||
|
||||
|
||||
要将这个 .dot 文件转换成一个图形映像,则需要使用 Dot 工具,这个工具是在 Graphviz 包中提供的。清单 6 介绍了这种转换。
|
||||
|
||||
清单 6. 使用 Dot 来创建 JPG 映像
|
||||
|
||||
$__ dot -Tjpg test.dot -o test.jpg__
|
||||
$
|
||||
|
||||
|
||||
在这段代码中,我告诉 Dot 使用 test.dot 图形规范,并生成一个 JPG 图像,将其保存在文件 test.jpg 中。所生成的图像如图 3 所示。在此处,我使用了 JPG 格式,但是 Dot 工具也可以支持其他格式,其中包括 GIF、PNG 和 postscript。
|
||||
{{./figure3.gif}}
|
||||
图 3. Dot 创建的示例图
|
||||
|
||||
===== Dot 创建的示例图 =====
|
||||
Dot 语言还可以支持其他一些选项,包括**外形、颜色和很多属性**。但是就我们想要实现的功能而言,这个选项就足够了。
|
||||
|
||||
|
||||
===== 综合 =====
|
||||
|
||||
现在我们已经看到了整个过程的各个阶段了,下面可以采用一个例子来展示如何将这些阶段合并在一起了。现在,您应该已经展开并安装了 Pvtrace 工具,然后还需要将 instrument.c 文件复制到**工作源代码目录中**。
|
||||
|
||||
在这个例子中,我使用了一个源文件 test.c 进行检测。清单 7 给出了整个过程。在第 3 行中,我使用__检测源(instrument.c)__来构建(编译并连接)应用程序。然后在第 4 行执行 test,再使用 ls 命令验证已经生成了 trace.txt 文件。在第 8 行,我调用了 Pvtrace 工具,并提供这个映像文件作为它惟一的参数。映像名是必需的,这样 Addr2line(在 Pvtrace 中调用)就可以访问这个映像中的调试信息。在第 9 行中,我又执行了一次 ls 命令,以确保 Pvtrace 生成了 graph.dot 文件。最后,在第 12 行,使用 Dot 将这个图形规范转换成一个 JPG 图形映像。
|
||||
|
||||
清单 7. 创建调用跟踪图的整个过程
|
||||
|
||||
1: $ ls
|
||||
2: instrument.c test.c
|
||||
3: $ __gcc -g -finstrument-functions test.c instrument.c -o test__
|
||||
4: $ ./test
|
||||
5: $ ls
|
||||
6: instrument.c test.c
|
||||
7: test trace.txt
|
||||
8: $ pvtrace test
|
||||
9: $ ls
|
||||
10: graph.dot test trace.txt
|
||||
11: instrument.c test.c
|
||||
12: $ dot -Tjpg graph.dot -o graph.jpg
|
||||
13: $ ls
|
||||
14: graph.dot instrument.c test.c
|
||||
15: graph.jpg test trace.txt
|
||||
16: $
|
||||
|
||||
这个过程的示例输出如图 4 所示。这个示例图是从使用 Q 学习的一个简单增强式学习应用程序中得到的。
|
||||
{{./figure4.gif}}
|
||||
|
||||
图 4. 示例应用程序的跟踪结果
|
||||
|
||||
===== 示例应用程序的跟踪结果 =====
|
||||
您也可以使用这种方法对更大的应用程序进行分析。我要展示的最后一个例子是 Gzip 工具。我简单地将 instrument.c 加入 Gzip 的 __Makefile__ 中,作为其依赖的一个源文件,然后编译 Gzip,并使用它生成一个跟踪文件。这个图形太大了,不太容易进行更详细的分析,但是下图表示了 Gzip 对一个小文件进行压缩时的处理过程。
|
||||
{{./figure5.jpg}}
|
||||
图 5. Gzip 跟踪结果
|
||||
Gzip 跟踪结果
|
||||
|
||||
===== 结束语 =====
|
||||
|
||||
使用开源软件和少量的中间代码,只需要花很少的时间就可以开发出非常有用的项目。通过使用对应用程序进行分析的几个 GNU 编译器扩展,可以使用 Addr2line 工具进行地址转换,并对 Graphviz 应用程序进行图形可视化,然后您就可以得到一个程序,该程序可以对应用程序进行分析,并展示一个说明调用链的定向图。通过图形来查看一个应用程序的调用链对于理解应用程序的内部行为来说非常重要。在正确了解调用链及其各自的频率之后,这些知识可能对调试和优化应用程序非常有用。
|
||||
116
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用/c++.txt
Normal file
@@ -0,0 +1,116 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-02-20T17:18:17+08:00
|
||||
|
||||
====== c++ ======
|
||||
Created Monday 20 February 2012
|
||||
|
||||
I can see the same behavior with gcc 3.4.1.
|
||||
|
||||
At least an obvious way to prevent that problem is
|
||||
to extract the __cyg_profile_func* stuff into a separated
|
||||
source file that is **compiled in C.**
|
||||
This object is then__ linked__ at the end with the C++ -compiled
|
||||
objects you can have to build the final binary.
|
||||
It works at least for my gcc 3.4.1.
|
||||
|
||||
|
||||
You can also tell g++ that t__his part of the code is C __by adding
|
||||
|
||||
注意:以上步骤都需加上-g __-finstrument-functions参数__
|
||||
extern "C"
|
||||
{
|
||||
/* the __cyg_profile_func... functions */
|
||||
|
||||
|
||||
}
|
||||
|
||||
Also tested with 3.4.1.
|
||||
|
||||
Regards,
|
||||
--
|
||||
Yannick Perret
|
||||
|
||||
|
||||
=======================================
|
||||
Dmitry Antipov wrote:
|
||||
|
||||
(This letter was being previously posted to gcc-help list, which is probably the
|
||||
better place to ask such questions. But since it wasn't answered there, I posted it here).
|
||||
|
||||
The following program
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function));
|
||||
void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function));
|
||||
|
||||
int depth = -1;
|
||||
|
||||
void __cyg_profile_func_enter (void *func, void *caller)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
depth++;
|
||||
for (n = 0; n < depth; n++)
|
||||
printf (" ");
|
||||
printf ("-> %p\n", func);
|
||||
}
|
||||
|
||||
|
||||
void __cyg_profile_func_exit (void *func, void *caller)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
for (n = 0; n < depth; n++)
|
||||
printf (" ");
|
||||
printf ("<- %p\n", func);
|
||||
depth--;
|
||||
}
|
||||
|
||||
|
||||
void bar(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void foo (void)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 4; x++)
|
||||
bar ();
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
foo ();
|
||||
bar ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
works as expected if it's compiled as a C program ('gcc -finstrument-functions self.c').
|
||||
But __cyg_* functions doesn't called if the program is compiled as C++ program
|
||||
('g++ -finstrument-fnctions self.cpp').
|
||||
|
||||
Looking through generated assembly shows that the calls of __cyg_* functions
|
||||
are emitted, but these functions itself are generated__ with mangled names.__
|
||||
Here is a piece of 'nm' output:
|
||||
|
||||
U __cyg_profile_func_enter
|
||||
U __cyg_profile_func_exit
|
||||
...
|
||||
00000050 T _Z23__cyg_profile_func_exitPvS_
|
||||
00000000 T _Z24__cyg_profile_func_enterPvS_
|
||||
...
|
||||
|
||||
|
||||
The documentation around '-finstrument-functions' says nothing about C vs. C++
|
||||
differences, so I'm confused why it doesn't work for C++ also.
|
||||
|
||||
GCC version is 3.4.3.
|
||||
|
||||
Thanks,
|
||||
BIN
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用/figure1.gif
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用/figure2.gif
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
BIN
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用/figure3.gif
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用/figure4.gif
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
Zim/Utils/Graphviz/用_Graphviz_可视化函数调用/figure5.jpg
Normal file
|
After Width: | Height: | Size: 40 KiB |
28
Zim/Utils/IRC.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-11-23T18:49:32+08:00
|
||||
|
||||
====== IRC ======
|
||||
Created Wednesday 23 November 2011
|
||||
|
||||
The official Arch Linux IRC channel is** #archlinux **on the Freenode network.
|
||||
#archlinux-cn Discussion (Chinese)
|
||||
#arch-cn Discussion (Chinese), on irc.oftc.net
|
||||
#fedora-cn
|
||||
#python
|
||||
#pylocal on Freenode is for Python user groups.
|
||||
#python-dev on Freenode is for CPython developers, where they can coordinate their work or discuss problems.
|
||||
#distutils on Freenode is for Python packaging discussion.
|
||||
#ubuntu Ubuntu help channel
|
||||
#ubuntu+1 Help channel for development versions
|
||||
#ubuntuforums Ubuntu Forums: support & community chat
|
||||
#ubuntu-beginners Ubuntu Beginners Team
|
||||
#ubuntu-cn Mainland China
|
||||
|
||||
#qt
|
||||
#linux
|
||||
#gento
|
||||
#git
|
||||
#c++
|
||||
#bash
|
||||
#emacs
|
||||
258
Zim/Utils/LAMP.txt
Normal file
@@ -0,0 +1,258 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-02T22:20:15+08:00
|
||||
|
||||
====== LAMP ======
|
||||
Created Monday 02 May 2011
|
||||
|
||||
===== LAMP =====
|
||||
This article describes how to set up the Apache web server on an Arch Linux system. It also tells how to optionally install PHP and MySQL and integrate these in the Apache server. This combination is commonly referred to as LAMP (Linux Apache MySQL PHP).
|
||||
If you only need a web server for development and testing, Xampp might be a better and easier option.
|
||||
Contents [hide]
|
||||
1 Installation
|
||||
2 Configuration
|
||||
2.1 Apache
|
||||
2.1.1 User dirs
|
||||
2.1.2 SSL
|
||||
2.1.3 Virtual Hosts
|
||||
2.1.4 Advanced Options
|
||||
2.2 PHP
|
||||
2.2.1 Advanced options
|
||||
2.3 MySQL
|
||||
3 Useful terminal shortcuts
|
||||
4 See also
|
||||
5 External links
|
||||
Installation
|
||||
|
||||
# pacman -S apache php php-apache mysql
|
||||
This document assumes you will install Apache, PHP and MySQL together. If desired however, you may install Apache, PHP, and MySQL separately and simply refer to the relevant sections below.
|
||||
Note: New default user and group: Instead of group "nobody", apache now runs as user/group "http" by default. You might want to adjust your httpd.conf according to this change, though you may still run httpd as nobody.
|
||||
Configuration
|
||||
|
||||
Apache
|
||||
For security reasons, as soon as Apache is started by the root user (directly or via startup scripts) it switches to the UID/GID specified in /etc/httpd/conf/httpd.conf
|
||||
Check for the existence of the http user by looking for http in the output of the following command:
|
||||
# grep http /etc/passwd
|
||||
Create the system user http if it does not exist already:
|
||||
# useradd -d /srv/http -r -s /bin/false -U http
|
||||
This creates the http user with home directory /srv/http/, as a system account (-r), with a bogus shell (-s /bin/false) and creates a group with the same name (-U).
|
||||
Add this line to /etc/hosts (If the file does not exist, create it.):
|
||||
127.0.0.1 localhost.localdomain localhost
|
||||
If you want a different hostname, append it to the end:
|
||||
127.0.0.1 localhost.localdomain localhost myhostname
|
||||
Edit /etc/rc.conf: If you set a hostname, the HOSTNAME variable should be the same; otherwise, use "localhost":
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
HOSTNAME="localhost"
|
||||
Make sure the hostname appears in /etc/hosts or apache will fail to start. Alternatively, you can
|
||||
edit /etc/httpd/conf/httpd.conf and comment the following module:
|
||||
LoadModule unique_id_module modules/mod_unique_id.so
|
||||
Customize your config. At least change httpd.conf and extra/httpd-default.conf to your liking. For security reasons, you might want to change ServerTokens Full to ServerTokens Prod and ServerSignature On to ServerSignature Off in extra/httpd-default.conf.
|
||||
Run the following in a terminal to start the HTTP server:
|
||||
# /etc/rc.d/httpd start
|
||||
Apache should now be running. Test by visiting http://localhost/ in a web browser. It should display a simple Apache test page. If you receive a 403 Error, comment out the following line in /etc/httpd/conf/httpd.conf:
|
||||
Include conf/extra/httpd-userdir.conf
|
||||
To start Apache automatically at boot, edit /etc/rc.conf and add the httpd daemon:
|
||||
DAEMONS=(... httpd ...)
|
||||
Or add this line to /etc/rc.local:
|
||||
/etc/rc.d/httpd start
|
||||
User dirs
|
||||
If you do not want user directories to be available on the web (e.g., ~/public_html on the machine is accessed as http://localhost/~user/), comment the following line in /etc/httpd/conf/httpd.conf since they are activated by default:
|
||||
Include conf/extra/httpd-userdir.conf
|
||||
You must make sure that your home directory permissions are set properly so that Apache can get there. Your home directory and ~/public_html/ must be executable for others ("rest of the world"). This seems to be enough:
|
||||
$ chmod o+x ~
|
||||
$ chmod o+x ~/public_html
|
||||
More secure way to share your home folder with apache is to add http user in group that your home folder belongs. For example, if your home folder and other sub-folders in your home folder belong to group piter, all you have to do is following:
|
||||
$ usermod -aG piter http
|
||||
Ofcourse, you have to give read and execute permissions on ~/, ~/public_html, and all other sub-folders in ~/public_html to the group members (group piter in our case). Do something like following (modify commands for your specific case):
|
||||
$ chmod g+xr-w /home/yourusername
|
||||
$ chmod -R g+xr-w /home/yourusername/public_html
|
||||
Note: This way you don't have to give access to your folder to every single user in order to give access to http user. Only http user and other potential users that are in piter group will have access to your home folder.
|
||||
And then
|
||||
$ /etc/rc.d/httpd restart
|
||||
to restart apache.
|
||||
SSL
|
||||
Create self-signed certificate (you can change key size and days of validity)
|
||||
# cd /etc/httpd/conf
|
||||
# openssl genrsa -des3 -out server.key 1024
|
||||
# openssl req -new -key server.key -out server.csr
|
||||
# cp server.key server.key.org
|
||||
# openssl rsa -in server.key.org -out server.key
|
||||
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
|
||||
In /etc/httpd/conf/httpd.conf uncomment line
|
||||
Include conf/extra/httpd-ssl.conf
|
||||
Restart apache
|
||||
# /etc/rc.d/httpd restart
|
||||
Virtual Hosts
|
||||
If you want to have more than one host, make sure you have
|
||||
# Virtual hosts
|
||||
Include conf/extra/httpd-vhosts.conf
|
||||
in /etc/httpd/conf/httpd.conf.
|
||||
In /etc/httpd/conf/extra/httpd-vhosts.conf set your virtual hosts according the example, e.g.:
|
||||
NameVirtualHost 127.0.0.1
|
||||
|
||||
<VirtualHost 127.0.0.1>
|
||||
ServerAdmin your@domainname1.dom
|
||||
DocumentRoot "/home/username/yoursites/domainname1.dom/www"
|
||||
ServerName domainname1.dom
|
||||
ServerAlias domainname1.dom
|
||||
<Directory /home/username/yoursites/domainname1.dom/www/>
|
||||
DirectoryIndex index.htm index.html
|
||||
AddHandler cgi-script .cgi .pl
|
||||
Options ExecCGI Indexes FollowSymLinks MultiViews +Includes
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost 127.0.0.1>
|
||||
ServerAdmin your@domainname2.dom
|
||||
DocumentRoot "/home/username/yoursites/domainname2.dom/www"
|
||||
ServerName domainname2.dom
|
||||
ServerAlias domainname2.dom
|
||||
<Directory /home/username/yoursites/domainname2.dom/www/>
|
||||
DirectoryIndex index.htm index.html
|
||||
AddHandler cgi-script .cgi .pl
|
||||
Options ExecCGI Indexes FollowSymLinks MultiViews +Includes
|
||||
AllowOverride None
|
||||
Order allow,deny
|
||||
allow from all
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
Add your virtual host names to your /etc/hosts file:
|
||||
127.0.0.1 domainname1.dom
|
||||
127.0.0.1 domainname2.dom
|
||||
Restart Apache:
|
||||
sudo /etc/rc.d/httpd restart
|
||||
If you setup your virtual hosts to be in your user directory, sometimes it interferes with Apaches 'Userdir' settings. To avoid problems disable 'Userdir' by commenting it out:
|
||||
# User home directories
|
||||
#Include conf/extra/httpd-userdir.conf
|
||||
As said above, take care, you have the proper permissions:
|
||||
sudo chmod 0775 /home/yourusername/
|
||||
If you have a huge amount of virtual hosts you easily want to dis- and enable, its recommended to create one config file per virtualhost and store them all in one folder, eg: /etc/httpd/conf/vhosts.
|
||||
First create the folder:
|
||||
sudo mkdir /etc/httpd/conf/vhosts
|
||||
Then place the single config files in them:
|
||||
sudo nano /etc/httpd/conf/vhosts/domainname1.dom
|
||||
sudo nano /etc/httpd/conf/vhosts/domainname2.dom
|
||||
...
|
||||
In the last step, "Include" the single configs in your /etc/httpd/conf/httpd.conf:
|
||||
#Enabled Vhosts:
|
||||
Include conf/vhosts/domainname1.dom
|
||||
#Include conf/vhosts/domainname1.dom
|
||||
You can enable and disable single virtual hosts by commenting them out or uncommenting them.
|
||||
Advanced Options
|
||||
These options in /etc/httpd/conf/httpd.conf might be interesting for you:
|
||||
# Listen 80
|
||||
This is the port Apache will listen to. For Internet-access with router, you have to forward the port.
|
||||
If you setup Apache for local development you may want it to be only accessible from your computer. Then change this line to:
|
||||
# Listen 127.0.0.1:80
|
||||
This is the admin's email-address which can be found on e.g. error-pages:
|
||||
# ServerAdmin sample@sample.com
|
||||
This is the directory where you should put your web pages:
|
||||
# DocumentRoot "/srv/http"
|
||||
Change it, if you want to, but do not forget to also change the
|
||||
<Directory "/srv/http">
|
||||
to whatever you changed your DocumentRoot to, or you will likely get a 403 error (lack of privileges) when you try to access the new document root. Do not forget to change the Deny from all line, otherwise you will get 403 error too.
|
||||
# AllowOverride None
|
||||
This directive in <Directory> sections causes apache to completely ignore .htaccess files. If you intend to use rewrite mod or other settings in .htaccess files, you can allow which directives declared in that file can override server configuration. For more info refer to http://httpd.apache.org/docs/current/mod/core.html#allowoverride
|
||||
Note: If you have issues with your configuration you can have apache check the configuration with: apachectl configtest
|
||||
PHP
|
||||
Install the "php-apache" package from extra using pacman.
|
||||
Add these lines in /etc/httpd/conf/httpd.conf:
|
||||
Place this in the "LoadModule" list anywhere after LoadModule dir_module modules/mod_dir.so:
|
||||
LoadModule php5_module modules/libphp5.so
|
||||
Place this at the end of the "Include" list:
|
||||
Include conf/extra/php5_module.conf
|
||||
Note: If you do not see libphp5.so in the Apache modules directory, you may have forgotten to install the php-apache package.
|
||||
If your DocumentRoot is not /srv/http, add it to open_basedir in /etc/php/php.ini as such:
|
||||
open_basedir=/srv/http/:/home/:/tmp/:/usr/share/pear/:/path/to/documentroot
|
||||
Restart the Apache service to make changes take effect:
|
||||
# /etc/rc.d/httpd restart
|
||||
A test file for PHP is included by default and can be found in /srv/http
|
||||
Remember to copy this file to ~/public_html if you permitted such a configuration.
|
||||
Test PHP: http://localhost/test.php or http://localhost/~myname/test.php
|
||||
If this file does not exist, just place the following in /srv/http/test.php:
|
||||
<?php phpinfo(); ?>
|
||||
If the PHP instruction is not executed (you see : <html>...</html>), check that you have added "Includes" to the "Options" line for your root directory. Moreover, make sure you have this line in your <IfModule mime_module> section:
|
||||
AddHandler application/x-httpd-php .php
|
||||
Advanced options
|
||||
Remember to add a file handler for .phtml if you need it in /etc/httpd/conf/extra/php5_module.conf:
|
||||
DirectoryIndex index.php index.phtml index.html
|
||||
If you want the libGD module, install php-gd package and uncomment in /etc/php/php.ini:
|
||||
Note: php-gd requires libpng, libjpeg, and freetype2
|
||||
;extension=gd.so
|
||||
to
|
||||
extension=gd.so
|
||||
Pay attention to which extension you uncomment, as this extension is sometimes mentioned in an explanatory comment before the actual line you want to uncomment.
|
||||
|
||||
If you want to display errors to debug your php code, change this line of /etc/php/php.ini:
|
||||
display_errors=Off
|
||||
to
|
||||
display_errors=On
|
||||
If you want the mcrypt module, install php-mcrypt package and uncomment in /etc/php/php.ini:
|
||||
;extension=mcrypt.so
|
||||
to
|
||||
extension=mcrypt.so
|
||||
Warning: If you get error like:
|
||||
[XXX Debug] PHP Notice: in file /index.php on line 86: date(): It is not safe to rely on the system'XXXX
|
||||
[XXX Debug] PHP Notice: in file /index.php on line 86: getdate(): It is not safe to rely on the system's timezone settings.XXXX
|
||||
change this line of /etc/php/php.ini
|
||||
;date.timezone =
|
||||
to
|
||||
date.timezone = Europe/Berlin
|
||||
Note: more infos about Time Zone in PHP
|
||||
restart httpd with
|
||||
# /etc/rc.d/httpd restart
|
||||
MySQL
|
||||
Configure MySQL as described in MySQL.
|
||||
Edit /etc/php/php.ini (this is in /usr/etc on older systems) to uncomment the following line (By removing ;):
|
||||
;extension=mysql.so
|
||||
;extension=mysqli.so
|
||||
Caution:Some users have reported typos on this line. Please make sure that it reads ;extension=mysql.so and not ;extension=msql.so.
|
||||
You can add minor privileged users for your web scripts by editing the tables found in the mysql database. You have to restart MySQL for changes to take effect. Do not forget to check the mysql/users table. If there is a second entry for root and your hostname is left with no password set, everybody from your host probably could gain full access. Perhaps see next section for these jobs.
|
||||
Run in terminal:
|
||||
# /etc/rc.d/mysqld start
|
||||
You may also need to restart Apache. Run in terminal:
|
||||
# /etc/rc.d/httpd restart
|
||||
MySQL should now be running. Set the root password and test it by running:
|
||||
# mysqladmin -u root password password
|
||||
# mysql -u root -p
|
||||
Type exit to exit from the CLI MySQL client
|
||||
Edit /etc/rc.conf (to start MySQL at boot):
|
||||
DAEMONS=(... mysqld ...)
|
||||
Or add this line to rc.local:
|
||||
/etc/rc.d/mysqld start
|
||||
You can get the "error no. 2013: Lost Connection to mysql server during query" message instantly whenever you try to connect to the MySQL daemon by TCP/IP. This is the TCP wrappers system (tcpd), which uses the hosts_access(5) system to allow or disallow connections.
|
||||
If you are running into this problem, be sure to add this to your /etc/hosts.allow file:
|
||||
# mysqld : ALL : ALLOW
|
||||
# mysqld-max : ALL : ALLOW
|
||||
# and similar for the other MySQL daemons.
|
||||
Note: The examples above are the simplest case, telling tcpd to allow connections from anywhere. You may wish to use a more-appropriate choice of permissible sources instead of 'ALL'. Just make sure that localhost and the IP address (numeric or DNS) of the interface by which you connect are specified.
|
||||
For example, a line like the following would overcome the "2013: Lost Connection" errors:
|
||||
# mysqld : 127.0.0.1 : ALLOW
|
||||
You might also need to edit /etc/mysql/my.cnf and comment out the skip-networking line as such:
|
||||
skip-networking
|
||||
to
|
||||
#skip-networking
|
||||
Tip: You may want to install phpmyadmin to work with your databases.
|
||||
Useful terminal shortcuts
|
||||
|
||||
Adding these to your ~/.bashrc file could save you a lot of typing:
|
||||
alias mysqls='sudo /etc/rc.d/mysqld' #mysqls start/stop/restart starts/stops/restarts mysql
|
||||
alias apache='sudo /etc/rc.d/httpd' #apache start/stop/restart starts/stops/restarts apache
|
||||
See also
|
||||
|
||||
MySQL - Article for MySQL
|
||||
PhpMyAdmin - Web frontend for MySQL typically found in LAMP environments
|
||||
Xampp - Self contained web-server that supports PHP, Perl, and MySQL
|
||||
|
||||
External links
|
||||
|
||||
http://www.apache.org/
|
||||
http://www.php.net/
|
||||
http://www.mysql.com/
|
||||
http://www.akadia.com/services/ssh_test_certificate.html
|
||||
http://wiki.apache.org/httpd/CommonMisconfigurations
|
||||
454
Zim/Utils/Linux_进程管理.txt
Normal file
@@ -0,0 +1,454 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-11-23T17:19:30+08:00
|
||||
|
||||
====== Linux 进程管理 ======
|
||||
Created Wednesday 23 November 2011
|
||||
http://www.linuxsir.org/main/node/210
|
||||
|
||||
作者:北南南北
|
||||
来自:LinuxSir.Org
|
||||
摘要:本文讲述的时进程管理的基本概念和进程管理工具介绍;文中的重点对进程管理工具的分类介绍及应用举例,包括 ps、pgrep、top 、kill、pkill、killall、nice和renice 等工具。
|
||||
|
||||
目录
|
||||
|
||||
1、程序和进程;
|
||||
|
||||
1.1 进程分类;
|
||||
1.2 进程的属性;
|
||||
1.3 父进程和子进程;
|
||||
|
||||
2、进程管理;
|
||||
2.1 ps 监视进程工具;
|
||||
|
||||
2.1.1 ps参数说明;
|
||||
2.1.2 ps 应用举例;
|
||||
|
||||
2.2 pgrep
|
||||
|
||||
3、终止进程的工具 kill 、killall、pkill、xkill;
|
||||
3.1 kill
|
||||
3.2 killall
|
||||
3.3 pkill
|
||||
3.4 xkill
|
||||
|
||||
4、top 监视系统任务的工具;
|
||||
4.1 top 命令用法及参数;
|
||||
4.2 top 应用举例;
|
||||
|
||||
5、进程的优先级: nice和renice;
|
||||
6、关于本文;
|
||||
7、后记;
|
||||
8、参考文档;
|
||||
9、相关文档;
|
||||
|
||||
|
||||
++++++++++++++++++++++++++++++++++++++
|
||||
正文
|
||||
++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
1、程序和进程;
|
||||
|
||||
程序是为了完成某种任务而设计的软件,比如OpenOffice是程序。什么是进程呢?进程就是运行中的程序。
|
||||
|
||||
一个运行着的程序,可能有多个进程。 比如 LinuxSir.Org 所用的WWW服务器是apache服务器,当管理员启动服务后,可能会有好多人来访问,也就是说许多用户来同时请求httpd服务,apache服务器将会创建有多个httpd进程来对其进行服务。
|
||||
|
||||
|
||||
1.1 进程分类;
|
||||
|
||||
进程一般分为__交互进程、批处理进程(后台进程)和守护进程__三类。
|
||||
|
||||
值得一提的是守护进程总是活跃的,一般是后台运行,守护进程一般是由系统在开机时通过脚本自动激活启动或超级管理用户root来启动。比如在Fedora或Redhat中,我们可以定义httpd 服务器的启动脚本的运行级别,此文件位于/etc/init.d目录下,文件名是httpd,/etc/init.d/httpd 就是httpd服务器的守护程序,当把它的运行级别设置为3和5时,当系统启动时,它会跟着启动。
|
||||
|
||||
[root@localhost ~]# chkconfig --level 35 httpd on
|
||||
|
||||
由于守护进程是一直运行着的,所以它所处的状态是等待请求处理任务。比如,我们是不是访问 LinuxSir.Org ,LinuxSir.Org 的httpd服务器都在运行,等待着用户来访问,也就是等待着任务处理。
|
||||
|
||||
|
||||
1.2 进程的属性;
|
||||
|
||||
进程ID(PID):是唯一的数值,用来区分进程;
|
||||
父进程和父进程的ID(PPID);
|
||||
启动进程的用户ID(UID)和所归属的组(GID);
|
||||
进程状态:状态分为运行R、休眠S、僵尸Z;
|
||||
进程执行的优先级;
|
||||
进程所连接的终端名;
|
||||
进程资源占用:比如占用资源大小(内存、CPU占用量);
|
||||
|
||||
|
||||
1.3 父进程和子进程;
|
||||
|
||||
他们的关系是管理和被管理的关系,当父进程终止时,子进程也随之而终止。但子进程终止,父进程并不一定终止。比如httpd服务器运行时,我们可以杀掉其子进程,父进程并不会因为子进程的终止而终止。
|
||||
|
||||
在进程管理中,当我们发现占用资源过多,或无法控制的进程时,应该杀死它,以保护系统的稳定安全运行;
|
||||
|
||||
|
||||
2、进程管理;
|
||||
|
||||
对于Linux进程的管理,是通过进程管理工具实现的,比如ps、kill、pgrep等工具;
|
||||
|
||||
|
||||
2.1 ps 监视进程工具;
|
||||
|
||||
ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;如果想对进程时间监控,应该用top工具;
|
||||
|
||||
2.1.1 ps 的参数说明;
|
||||
|
||||
ps 提供了很多的选项参数,常用的有以下几个;
|
||||
|
||||
|
||||
a 显示所有用户的所有进程(包括其它用户);
|
||||
x 显示无控制终端的进程;
|
||||
r 显示运行中的进程;
|
||||
|
||||
l 长格式输出;
|
||||
u 按用户名和启动时间的顺序来显示进程;
|
||||
j 用任务格式来显示进程;
|
||||
f 用树形格式来显示进程;
|
||||
ww 避免详细参数被截断;
|
||||
|
||||
我们常用的选项是组合是aux 或lax,还有参数f的应用;
|
||||
|
||||
ps aux 或lax输出的解释;
|
||||
|
||||
USER 进程的属主;
|
||||
PID 进程的ID;
|
||||
PPID 父进程;
|
||||
%CPU 进程占用的CPU百分比;
|
||||
%MEM 占用内存的百分比;
|
||||
NI 进程的NICE值,数值大,表示较少占用CPU时间;
|
||||
VSZ 进程虚拟大小;
|
||||
RSS 驻留中页的数量;
|
||||
WCHAN
|
||||
TTY 终端ID
|
||||
STAT 进程状态
|
||||
|
||||
D Uninterruptible sleep (usually IO)
|
||||
R 正在运行可中在队列中可过行的;
|
||||
S 处于休眠状态;
|
||||
T 停止或被追踪;
|
||||
W 进入内存交换(从内核2.6开始无效);
|
||||
X 死掉的进程(从来没见过);
|
||||
Z 僵尸进程;
|
||||
|
||||
< 优先级高的进程
|
||||
N 优先级较低的进程
|
||||
L 有些页被锁进内存;
|
||||
s 进程的领导者(在它之下有子进程);
|
||||
l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
|
||||
+ 位于后台的进程组;
|
||||
|
||||
|
||||
WCHAN 正在等待的进程资源;
|
||||
START 启动进程的时间;
|
||||
TIME 进程消耗CPU的时间;
|
||||
COMMAND 命令的名称和参数;
|
||||
|
||||
|
||||
=== 2.1.2 ps 应用举例; ===
|
||||
|
||||
实例一:ps aux 最常用
|
||||
|
||||
[root@localhost ~]# ps -aux |more
|
||||
|
||||
可以用 | 管道和 more 连接起来分页查看;
|
||||
|
||||
[root@localhost ~]# ps -aux > ps001.txt
|
||||
[root@localhost ~]# more ps001.txt
|
||||
|
||||
这里是把所有进程显示出来,并输出到ps001.txt文件,然后再通过more 来分页查看;
|
||||
|
||||
实例二:和grep 结合,提取指定程序的进程;
|
||||
|
||||
[root@localhost ~]# ps aux |grep httpd
|
||||
root 4187 0.0 1.3 24236 10272 ? Ss 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4189 0.0 0.6 24368 4940 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4190 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4191 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4192 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4193 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4194 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4195 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4196 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd
|
||||
root 4480 0.0 0.0 5160 708 pts/3 R+ 12:20 0:00 grep httpd
|
||||
|
||||
实例二:父进和子进程的关系友好判断的例子
|
||||
|
||||
[root@localhost ~]# ps auxf |grep httpd
|
||||
root 4484 0.0 0.0 5160 704 pts/3 S+ 12:21 0:00 \_ grep httpd
|
||||
root 4187 0.0 1.3 24236 10272 ? Ss 11:55 0:00 /usr/sbin/httpd
|
||||
apache 4189 0.0 0.6 24368 4940 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4190 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4191 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4192 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4193 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4194 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4195 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
apache 4196 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd
|
||||
|
||||
这里用到了f参数;父与子关系一目了然;
|
||||
|
||||
|
||||
=== 2.2 ===
|
||||
__pgrep__
|
||||
|
||||
=== 功能相同的工具还有 ===
|
||||
__pidof, 但是前者在指定进程名时可以使用正则表达式,后则不行.__
|
||||
|
||||
pgrep 是通过**程序的名字**来查询进程的工具,一般是用来判断**程序是否正在运行**。在服务器的配置和管理中,这个工具常被应用,简单明了;
|
||||
|
||||
用法:
|
||||
|
||||
#ps 参数选项 程序名
|
||||
|
||||
常用参数
|
||||
|
||||
-l 列出程序名和进程ID;
|
||||
-o 进程起始的ID;
|
||||
-n 进程终止的ID;
|
||||
|
||||
举例:
|
||||
|
||||
[root@localhost ~]# pgrep -lo httpd
|
||||
4557 httpd
|
||||
|
||||
[root@localhost ~]# pgrep -ln httpd
|
||||
4566 httpd
|
||||
|
||||
[root@localhost ~]# pgrep -l httpd
|
||||
4557 httpd
|
||||
4560 httpd
|
||||
4561 httpd
|
||||
4562 httpd
|
||||
4563 httpd
|
||||
4564 httpd
|
||||
4565 httpd
|
||||
4566 httpd
|
||||
|
||||
[root@localhost ~]# pgrep httpd
|
||||
4557
|
||||
4560
|
||||
4561
|
||||
4562
|
||||
4563
|
||||
4564
|
||||
4565
|
||||
4566
|
||||
|
||||
|
||||
=== 3、终止进程的工具 kill 、killall、pkill、xkill; ===
|
||||
|
||||
终止一个进程或终止一个正在运行的程序,一般是通过 kill 、killall、pkill、xkill 等进行。比如一个程序已经死掉,但又不能退出,这时就应该考虑应用这些工具。
|
||||
|
||||
另外应用的场合就是在服务器管理中,在不涉及数据库服务器程序的父进程的停止运行,也可以用这些工具来终止。为什么数据库服务器的父进程不能用这些工具杀死呢?原因很简单,这些工具在强行终止数据库服务器时,会让数据库产生更多的**文件碎片**,当碎片达到一定程度的时候,数据库就有崩溃的危险。比如mysql服务器最好是按其正常的程序关闭,而不是用pkill mysqld 或killall mysqld 这样危险的动作;当然对于占用资源过多的数据库子进程,我们应该用kill 来杀掉。
|
||||
|
||||
==== 3.1 kill ====
|
||||
|
||||
kill的应用是和ps 或pgrep 命令结合在一起使用的;
|
||||
|
||||
kill 的用法:
|
||||
|
||||
kill [信号代码] 进程ID
|
||||
|
||||
注:信号代码可以省略;我们常用的信号代码是__ -9 __,表示强制终止;
|
||||
|
||||
举例:
|
||||
|
||||
[root@localhost ~]# ps auxf |grep httpd
|
||||
root 4939 0.0 0.0 5160 708 pts/3 S+ 13:10 0:00 \_ grep httpd
|
||||
root 4830 0.1 1.3 24232 10272 ? Ss 13:02 0:00 /usr/sbin/httpd
|
||||
apache 4833 0.0 0.6 24364 4932 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4834 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4835 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4836 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4837 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4838 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4839 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
apache 4840 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd
|
||||
|
||||
我们查看httpd 服务器的进程;您也可以用__pgrep -l httpd __来查看;
|
||||
|
||||
我们看上面例子中的第二列,就是进程PID的列,其中4830是httpd服务器的父进程,从4833-4840的进程都是它4830的子进程;如果我们杀掉父进程4830的话,其下的子进程也会跟着死掉;
|
||||
|
||||
[root@localhost ~]# kill 4840 注:杀掉4840这个进程;
|
||||
|
||||
[root@localhost ~]# ps -auxf |grep httpd 注:查看一下会有什么结果?是不是httpd服务器仍在运行?
|
||||
[root@localhost ~]# kill 4830 注:杀掉httpd的父进程;
|
||||
[root@localhost ~]# ps -aux |grep httpd 注:查看httpd的其它子进程是否存在,httpd服务器是否仍在运行?
|
||||
|
||||
对于僵尸进程,可以用kill -9 来强制终止退出;
|
||||
|
||||
比如一个程序已经彻底死掉,如果kill 不加信号强度是没有办法退出,最好的办法就是加信号强度 -9 ,后面要接杀父进程;比如;
|
||||
|
||||
[root@localhost ~]# ps aux |grep gaim
|
||||
beinan 5031 9.0 2.3 104996 17484 ? S 13:23 0:01 gaim
|
||||
root 5036 0.0 0.0 5160 724 pts/3 S+ 13:24 0:00 grep gaim
|
||||
|
||||
或
|
||||
|
||||
[root@localhost ~]# pgrep -l gaim
|
||||
5031 gaim
|
||||
[root@localhost ~]# kill -9 5031
|
||||
|
||||
|
||||
=== 3.2 killall ===
|
||||
|
||||
killall 通过程序的名字,直接杀死所有进程,咱们简单说一下就行了。
|
||||
|
||||
|
||||
用法:killall 正在运行的程序名
|
||||
|
||||
killall 也和ps或pgrep 结合使用,比较方便;通过ps或pgrep 来查看哪些程序在运行;
|
||||
|
||||
举例:
|
||||
|
||||
[root@localhost beinan]# pgrep -l gaim
|
||||
2979 gaim
|
||||
|
||||
[root@localhost beinan]# killall gaim
|
||||
|
||||
|
||||
=== 3.3 pkill ===
|
||||
|
||||
pkill 和killall 应用方法差不多,也是直接杀死运行中的程序;如果您想杀掉单个进程,请用kill 来杀掉。
|
||||
|
||||
应用方法:
|
||||
|
||||
#pkill 正在运行的程序名
|
||||
|
||||
举例:
|
||||
|
||||
[root@localhost beinan]# pgrep -l gaim
|
||||
2979 gaim
|
||||
|
||||
[root@localhost beinan]# pkill gaim
|
||||
|
||||
|
||||
=== 3.4 xkill ===
|
||||
|
||||
xkill 是在桌面用的杀死图形界面的程序。比如当firefox 出现崩溃不能退出时,点鼠标就能杀死firefox 。当xkill运行时出来和个人脑骨的图标,哪个图形程序崩溃一点就OK了。如果您想终止xkill ,就按右键取消;
|
||||
|
||||
xkill 调用方法:
|
||||
|
||||
[root@localhost ~]# xkill
|
||||
|
||||
|
||||
==== 4、top 监视系统任务的工具; ====
|
||||
|
||||
和ps 相比,top是动态监视系统任务的工具,top 输出的结果是连续的;
|
||||
|
||||
|
||||
4.1 top 命令用法及参数;
|
||||
|
||||
top 调用方法:
|
||||
|
||||
top 选择参数
|
||||
|
||||
参数:
|
||||
|
||||
**-b ** 以批量模式运行,但不能接受命令行输入;
|
||||
-c 显示命令行,而不仅仅是命令名;
|
||||
**-d** N 显示两次刷新时间的间隔,比如 -d 5,表示两次刷新间隔为5秒;
|
||||
-i 禁止显示空闲进程或僵尸进程;
|
||||
**-n **NUM 显示更新次数,然后退出。比如 -n 5,表示top更新5次数据就退出;
|
||||
-p PID 仅监视指定进程的ID;PID是一个数值;
|
||||
-q 不经任何延时就刷新;
|
||||
-s 安全模式运行,禁用一些效互指令;
|
||||
-S 累积模式,输出每个进程的总的CPU时间,包括已死的子进程;
|
||||
|
||||
|
||||
交互式命令键位:
|
||||
|
||||
space 立即更新;
|
||||
c 切换到命令名显示,或显示整个命令(包括参数);
|
||||
f,F 增加显示字段,或删除显示字段;
|
||||
h,? 显示有关安全模式及累积模式的帮助信息;
|
||||
__k __提示输入要杀死的进程ID,目的是用来杀死该进程(默人信号为15)
|
||||
i 禁止空闲进程和僵尸进程;
|
||||
__l __切换到显法负载平均值和正常运行的时间等信息;
|
||||
__m __切换到内存信息,并以内存占用大小排序;
|
||||
n 提示显示的进程数,比如输入3,就在整屏上显示3个进程;
|
||||
o,O 改变显示字段的顺序;
|
||||
__r __把renice 应用到一个进程,提示输入PID和renice的值;
|
||||
s 改变两次刷新时间间隔,以秒为单位;
|
||||
t 切换到显示进程和CPU状态的信息;
|
||||
A 按进程生命大小进行排序,最新进程显示在最前;
|
||||
M 按内存占用大小排序,由大到小;
|
||||
N 以进程ID大小排序,由大到小;
|
||||
P 按CPU占用情况排序,由大到小
|
||||
S 切换到累积时间模式;
|
||||
T 按时间/累积时间对任务排序;
|
||||
W 把当前的配置写到~/.toprc中;
|
||||
|
||||
|
||||
=== 4.2 top 应用举例; ===
|
||||
|
||||
[root@localhost ~]# top
|
||||
|
||||
然后根据前面所说交互命令按个尝试一下就明白了,比如按M,就按内存占用大小排序;这个例子举不举都没有必要了。呵。。。。。。
|
||||
|
||||
当然您可以把top的输出传到一个文件中;
|
||||
|
||||
[root@localhost ~]# top > mytop.txt
|
||||
|
||||
然后我们就可以查看mytop文件,以慢慢的分析系统进程状态;
|
||||
|
||||
|
||||
===== 5、进程的优先级:nice和renice; =====
|
||||
|
||||
在Linux 操作系统中,进程之间是竟争资源(比如CPU和内存的占用)关系。这个竟争优劣是通过一个数值来实现的,也就是谦让度。高谦让度表示进程优化级别最低。负值或0表示对高优点级,对其它进程不谦让,也就是拥有优先占用系统资源的权利。谦让度的值从 -20到19。
|
||||
|
||||
目前硬件技术发展极速,在大多情况下,不必设置进程的优先级,除非在进程失控而疯狂占用资源的情况下,我们有可能来设置一下优先级,但我个人感觉没有太大的必要,在迫不得已的情况下,我们可以杀掉失控进程。
|
||||
|
||||
nice 可以在创建进程时,为进程指定谦让度的值,进程的优先级的值是父进程SHELL的优先级的值与我们所指定谦让度的相加和。所以我们在用nice设置程序的优先级时,所指定数值是一个增量,并不是优先级的绝对值;
|
||||
|
||||
nice 的应用举例:
|
||||
|
||||
[root@localhost ~]# nice -n 5 gaim & 注:运行gaim程序,并为它指定谦让度增量为5;
|
||||
|
||||
所以nice的最常用的应用就是:
|
||||
|
||||
nice -n 谦让度的增量值 程序
|
||||
|
||||
renice 是通过进程ID(PID)来改变谦让度,进而达到更改进程的优先级。
|
||||
|
||||
renice 谦让度 PID
|
||||
|
||||
renice 所设置的谦让度就是进程的绝对值;看下面的例子;
|
||||
|
||||
[root@localhost ~]# ps lax |grep gaim
|
||||
4 0 4437 3419 10 -5 120924 20492 - S< pts/0 0:01 gaim
|
||||
0 0 4530 3419 10 -5 5160 708 - R<+ pts/0 0:00 grep gaim
|
||||
|
||||
[root@localhost ~]# renice -6 4437
|
||||
4437: old priority -5, new priority -6
|
||||
|
||||
[root@localhost ~]# ps lax |grep gaim
|
||||
4 0 4437 3419 14 -6 120924 20492 - S< pts/0 0:01 gaim
|
||||
0 0 4534 3419 11 -5 5160 708 - R<+ pts/0 0:00 grep gaim
|
||||
|
||||
|
||||
6、关于本文;
|
||||
|
||||
进程管理还是需要的,虽然在桌面应用上,我们点鼠标就能完成大多的工作,但在服务器管理中,进程管理还是十分重要的。
|
||||
|
||||
有的弟兄会说,为什么您不说说在桌面环境中的图形管理的进程工具。我感觉没有太大的必要,如果您会点鼠标就应该能找到有关进程管理的工具。
|
||||
|
||||
还有的弟兄会说:Windows的进程管理真的很方便,按一下CTRL+ALT+DEL就可以调出来,随便你怎么杀和砍。我感觉Windows的进程管理并不怎么样,如果有的程序真的需要CTRL+ALT+DEL的话,呵,那肯定会出现系统假死现象。或者程序错误之类的提示。弄不好就得重启,这是事实吧。
|
||||
|
||||
Windows 的进程管理并不优秀,只是一个友好的界面而已,我想我说的没错吧;
|
||||
|
||||
|
||||
7、后记;
|
||||
|
||||
近些天一直在为网络基础文档做计划,当然也随手写一写自己能写的文档, 比如本篇就是; 也想把论坛中的一些弟兄优秀的教程整理出来,但后来一想,如果提交到 LinuxSir.Org 首页上,肯定得做一些修改,如果我来修改倒不如让作者自己来修改,自己写的东西自己最明白,对不对???
|
||||
|
||||
在准备网络文档计划的过程中,向etony兄请教了一些基本的网络基础知识。我对网络基础理论基本不懂。听tony兄解说的同时,我也做了笔记。同时也和tony兄讨论了网络基础篇的布局和谋篇的事,这关系到初学者入手的问题,好象是小事,其实事情比较大。如果写的文档,新手读不懂,老鸟又认为没有价值,我看倒不如不写。。
|
||||
|
||||
|
||||
8、参考文档;
|
||||
|
||||
|
||||
|
||||
9、相关文档;
|
||||
441
Zim/Utils/Mutt.txt
Normal file
@@ -0,0 +1,441 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-28T13:12:45+08:00
|
||||
|
||||
====== Mutt ======
|
||||
Created Wednesday 28 December 2011
|
||||
https://wiki.archlinux.org/index.php/Mutt
|
||||
|
||||
Mutt is a **text-based** mail client renowned for its powerful features. Though over a decade old, Mutt remains the mail client of choice for a great number of power-users. Unfortunately, a default Mutt install is plagued by complex keybindings along with a daunting amount of documentation. This guide will help the average user get Mutt up and running, and begin customizing it to their particular needs.
|
||||
Contents
|
||||
1 Overview
|
||||
2 Installing
|
||||
2.1 Notes
|
||||
3 Configuring
|
||||
3.1 IMAP
|
||||
3.1.1 Using native IMAP support
|
||||
3.1.1.1 imap_user
|
||||
3.1.1.2 imap_pass
|
||||
3.1.1.3 folder
|
||||
3.1.1.4 spoolfile
|
||||
3.1.1.5 mailboxes
|
||||
3.1.1.6 Summary
|
||||
3.1.2 External IMAP support
|
||||
3.2 POP3
|
||||
3.2.1 Retrieving mail
|
||||
3.2.1.1 More than one Email account with getmail
|
||||
3.2.2 Sorting mail
|
||||
3.3 Maildir
|
||||
3.4 SMTP
|
||||
3.4.1 Using native SMTP support
|
||||
3.4.2 External SMTP support
|
||||
4 Customizing
|
||||
4.1 Printing
|
||||
4.2 Signature block
|
||||
4.2.1 Random signature
|
||||
4.3 Viewing URLs & opening Firefox
|
||||
4.4 Mutt and Vim
|
||||
4.5 Viewing HTML within a Vim/Mutt setup
|
||||
4.6 Mutt and GNU nano
|
||||
4.7 Colors
|
||||
5 Tips & Tricks
|
||||
5.1 Use Mutt to send mail from command line
|
||||
5.2 How to display another email while composing
|
||||
6 Additional resources
|
||||
|
||||
===== Overview =====
|
||||
|
||||
Mutt focuses primarily on being a** Mail User Agent** (MUA), and was originally written to view mail. Later implementations added for retrieval, sending, and filtering mail are simplistic compared to other mail applications and, as such, users may wish to use __external applications__ to extend Mutt's capabilities.
|
||||
|
||||
Nevertheless, the Arch Linux mutt package is compiled with **IMAP, POP3 and SMTP** support, removing the necessity for external applications.
|
||||
|
||||
This article covers using both **native** IMAP sending and retrieval, and a setup depending on **OfflineIMAP** or **getmail (POP3)** to retrieve mail, **procmail **to filter it in the case of POP3, and **msmtp** to send it.
|
||||
|
||||
===== Installing =====
|
||||
|
||||
Install Mutt:
|
||||
|
||||
# pacman -S mutt
|
||||
|
||||
Optionally install **external helper applications** for an IMAP setup:
|
||||
|
||||
# pacman -S offlineimap msmtp
|
||||
|
||||
Or if using POP3:
|
||||
|
||||
# pacman -S getmail procmail
|
||||
|
||||
Notes
|
||||
|
||||
* If you just need the authentication methods LOGIN and PLAIN, these are satisfied with the dependency **libsasl**.
|
||||
* If you want to (or have to) use CRAM-MD5, GSSAPI or DIGEST-MD5, install also the package **cyrus-sasl-plugins**.
|
||||
* if you are using Gmail as your smtp server, you may need to install the package **cyrus-sasl**.
|
||||
|
||||
===== Configuring =====
|
||||
|
||||
This section covers IMAP, #POP3, #Maildir and #SMTP configuration.
|
||||
|
||||
Note that Mutt will recognize two locations for its configuration file; **~/.muttrc** and** ~/.mutt/muttrc**. Either location will work.
|
||||
|
||||
==== IMAP ====
|
||||
|
||||
//Native and external setups//
|
||||
|
||||
=== Using native IMAP support ===
|
||||
|
||||
The pacman version of Mutt is compiled with IMAP support. At the very least you need to have 4 lines in your muttrc file to be able to access your mail.
|
||||
* **imap_user**
|
||||
set imap_user=USERNAME
|
||||
Continuing with the previous example, remember that Gmail requires your **full **email address (this is not standard):
|
||||
set imap_user=your.username@gmail.com
|
||||
* **imap_pass**
|
||||
If unset, the password will be prompted for.
|
||||
set imap_pass=SECRET
|
||||
* **folder**
|
||||
Instead of a local directory which contains all your mail (and directories), **use your server** (and the highest folder in the hierarchy, if needed).
|
||||
set folder=imap[s]://imap.server.domain[:port]/[folder/]
|
||||
You do not have to use a folder, but it might be convenient if you have all your other folders inside your__ INBOX__, for example. Whatever you set here as your folder can be accessed later in Mutt with just an equal sign (=). Example:
|
||||
set folder=imaps://imap.gmail.com/
|
||||
* **spoolfile #服务器上存有所有邮件的文件夹**
|
||||
You can now use '=' or '+' as a **substitution** for the__ full folder path__ that was configured above. For example:
|
||||
set spoolfile=+INBOX #+INBOX是imaps://imap.gmail.com/INBOX的简写,+的内容由上面的folder变量替换
|
||||
* **mailboxes #服务器上存有邮件的各个文件夹**
|
||||
**Any imap folders** that should be checked regularly for new mail __should be__ listed here:
|
||||
mailboxes **=**INBOX **=**family #检查服务器上的两个文件夹内容是否有邮件,与下一条设置等效。
|
||||
mailboxes imaps://imap.gmail.com/INBOX imaps://imap.gmail.com/family
|
||||
Alternatively, check for **all **subscribed IMAP folders (as if all were added with a mailboxes line):
|
||||
set imap_check_subscribed
|
||||
These two versions are equivalent, but the first is much more convenient. Also, newer Mutt versions are configured by default to include a macro bound to the__ 'y' key__ which will allow you to change to any of the folders listed under mailboxes.
|
||||
|
||||
=== Summary ===
|
||||
Using these options, you will be able to start mutt, enter your IMAP password, and start reading your mail. Here is a muttrc snippet (for Gmail) with some other lines you might consider adding for better IMAP support.
|
||||
|
||||
set folder = imaps://imap.gmail.com/ #服务器地址,该值在以后可以用+代替
|
||||
set imap_user = your.username@gmail.com
|
||||
set imap_pass = your-imap-password
|
||||
set spoolfile = +INBOX
|
||||
mailboxes = +INBOX #只检索服务器上该目录下的邮件
|
||||
|
||||
# store **message headers** locally to speed things up
|
||||
set header_cache = ~/.mutt/hcache
|
||||
|
||||
# specify where to save and/or look for postponed messages
|
||||
set postponed = +[Gmail]/Drafts
|
||||
|
||||
# allow mutt to open new imap connection automatically
|
||||
unset imap_passive
|
||||
|
||||
# keep imap connection alive by polling intermittently (time in seconds)
|
||||
set imap_keepalive = 300
|
||||
|
||||
# how often to check for new mail (time in seconds)
|
||||
set mail_check = 120
|
||||
|
||||
===== External IMAP support =====
|
||||
|
||||
While IMAP-functionality is built into Mutt, it** does not download mail for offline-use**. The OfflineIMAP article describes how to download your emails to a__ local folder__ which can then be processed by Mutt.
|
||||
|
||||
Consider using applications such as spamassassin or imapfilter to __sort__ mail.
|
||||
|
||||
==== POP3 ====
|
||||
|
||||
//Retrieving and sorting mail with external applications//
|
||||
|
||||
=== Retrieving mail ===
|
||||
|
||||
Create the directory ~/.getmail/. Open the file **~/.getmail/getmailrc** in your favorite text editor.
|
||||
Here is an example getmailrc used with a gmail account.
|
||||
|
||||
[retriever]
|
||||
type = SimplePOP3SSLRetriever
|
||||
server = pop.gmail.com
|
||||
username = username@gmail.com
|
||||
port = 995
|
||||
password = password
|
||||
|
||||
[destination]
|
||||
type = Maildir
|
||||
path = ~/mail/
|
||||
|
||||
You can tweak this to your POP3 service's specification.
|
||||
|
||||
As you can see ~/.getmail/getmailrc contains **sensitive information **(namely, email account passwords in plain text). You will want to change access permissions to the directory so only the owner can see it:
|
||||
|
||||
$ chmod 700 ~/.getmail
|
||||
|
||||
For this guide we will be storing our mail in the maildir format. The two main mailbox formats are mbox and maildir. The main difference between the two is that mbox is one file, with all of your mails and their headers stored in it, whereas a maildir is a directory tree. Each mail is its own file, which will often speed things up.
|
||||
|
||||
A maildir is just a folder with the folders cur, new and tmp in it.
|
||||
|
||||
mkdir -p [[~/mail/{cur,new,tmp}]] #如果使用procmail,则这些目录不用创建
|
||||
|
||||
Now, run getmail. If it works fine, you can create a cronjob for getmail to run every n hours/minutes. Type crontab -e to edit cronjobs, and enter the following:
|
||||
|
||||
*/30 * * * * /usr/bin/getmail
|
||||
|
||||
That will run getmail every 30 minutes.
|
||||
More than one Email account with getmail
|
||||
|
||||
By default, when you run getmail the program searches for the file getmailrc created as seen above. If you have more than one mail account you would like to get mail from, then you can create such a file for each email address, and then tell getmail to run using both of them. Obviously if you have two accounts and two files you cannot have both of them called getmailrc. What you do is give them two different names, using myself as an example: I call one personal, and one university. These two files contain content relevant to my personal mail, and my university work mail respectively. Then to get getmail to work on these two files, instead of searching for getmailrc(default), I use the --rcfile switch like so: __getmail --rcfile__ university --rcfile personal This can work with more files if you have more email accounts, just make sure each file is in the .getmail directory and make sure to alter the cronjob to run the command with the --rcfile switches. E.g.
|
||||
|
||||
*/30 * * * * /usr/bin/getmail --rcfile university --rcfile personal
|
||||
|
||||
Obviously you can call your files whatever you want, providing you include them in the cronjob or shell command, and they are in the .getmail/ directory, getmail will fetch mail from those two accounts.
|
||||
|
||||
===== Sorting mail =====
|
||||
|
||||
**Procmail **is an extremely powerful sorting tool. For the purposes of this wiki, we will do some primitive sorting to get started.
|
||||
|
||||
You must edit your **getmailrc** to pass retrieved mail to procmail:
|
||||
|
||||
[destination]
|
||||
type = MDA_external
|
||||
path = /usr/bin/procmail
|
||||
|
||||
Now, open up __.procmailrc__ in your favorite editor. The following will sort all mail from the happy-kangaroos mailing list, and all mail from your lovey-dovey friend in their own maildirs.
|
||||
|
||||
MAILDIR=$HOME/mail
|
||||
DEFAULT=$MAILDIR/inbox/
|
||||
LOGFILE=$MAILDIR/log
|
||||
|
||||
:0:
|
||||
* ^To: happy-kangaroos@nicehost.com
|
||||
happy-kangaroos/
|
||||
|
||||
:0:
|
||||
* ^From: loveydovey@iheartyou.net
|
||||
lovey-dovey/
|
||||
|
||||
:0:
|
||||
inbox/
|
||||
|
||||
After you have saved your .procmailrc, run getmail and see if procmail succeeds in sorting your mail into the appropriate directories.
|
||||
Note: One easy to make mistake with .procmailrc is the permission. procmail require it to have permission__ 644__ and will not give meaningless error message if you do not.
|
||||
|
||||
===== Maildir =====
|
||||
|
||||
Maildir is a generic and standardized format. Almost every MUA is able to handle Maildirs and Mutt's support is excellent. There are just a few simple things that you need to do to get Mutt to use them. Open your muttrc with and add the following lines:
|
||||
|
||||
set mbox_type=Maildir
|
||||
set folder=$HOME/mail
|
||||
set spoolfile=+/inbox
|
||||
set header_cache=~/.hcache
|
||||
|
||||
This is a minimal Configuration that enables you to access your Maildir and checks for new local Mails in INBOX. This configuration also caches the headers of the eMails to speed up directory-listings. It might not be enabled in your build (but it sure is in the Arch-Package). Note that this does not affect OfflineIMAP in any way. It always syncs the all directories on a Server. spoolfile tells Mutt which local directories to poll for new Mail. You might want to add more Spoolfiles (for example the Directories of Mailing-Lists) and maybe other things. But this is subject to the Mutt manual and beyond the scope of this document.
|
||||
|
||||
===== SMTP =====
|
||||
|
||||
Whether you use POP or IMAP to receive mail you will probably still send mail using SMTP.
|
||||
|
||||
=== Using native SMTP support ===
|
||||
|
||||
The pacman version of Mutt is also compiled with SMTP support. Just check the online manual muttrc, or man muttrc for more information.
|
||||
For example:
|
||||
|
||||
set my_pass='mysecretpass'
|
||||
set my_user=myname@gmail.com
|
||||
|
||||
set smtp_url=smtps://$my_user:$my_pass@smtp.gmail.com
|
||||
set ssl_force_tls = yes
|
||||
|
||||
==== External SMTP support ====
|
||||
|
||||
An external SMTP agenta such as __msmtp__ or SSMTP can also be used. This section exclusively covers configuring Mutt for msmtp.
|
||||
|
||||
Edit Mutt's configuration file or create it if unpresent:
|
||||
**muttrc**
|
||||
|
||||
set realname='Disgruntled Kangaroo'
|
||||
|
||||
set sendmail="/usr/bin/msmtp"
|
||||
|
||||
set edit_headers=yes
|
||||
set folder=~/mail
|
||||
set mbox=+mbox
|
||||
set spoolfile=+inbox
|
||||
set record=+sent
|
||||
set postponed=+drafts
|
||||
set mbox_type=Maildir
|
||||
|
||||
**mailboxes **+inbox +lovey-dovey +happy-kangaroos
|
||||
|
||||
Now, startup mutt:
|
||||
|
||||
$ mutt
|
||||
|
||||
You should see all the mail in __~/mail/inbox__. Press m to compose mail; it will use the editor defined by your EDITOR environment variable. If this variable is not set, type:
|
||||
|
||||
$ export EDITOR=editorbin
|
||||
|
||||
For testing purposes, address the letter to yourself. After you have written the letter, save and exit the editor. You will return to Mutt, which will now show information about your e-mail. Press y to send it.
|
||||
|
||||
===== Customizing =====
|
||||
|
||||
Guides to get you started with using & customizing Mutt :
|
||||
|
||||
* My first mutt (maintained by Bruno Postle)
|
||||
* The Woodnotes Guide to the Mutt Email Client (maintained by Randall Wood)
|
||||
|
||||
If you have any Mutt specific questions, feel free to ask in the irc channel.
|
||||
|
||||
===== Printing =====
|
||||
|
||||
You can install __muttprint__ from the AUR for a fancier printing quality. In your muttrc file, insert:
|
||||
|
||||
set print_command="/usr/bin/muttprint %s -p {PrinterName}"
|
||||
|
||||
===== Signature block =====
|
||||
|
||||
Create a __.signature__ in your home directory. Your signature will be **appended** at the end of your email.
|
||||
|
||||
==== Random signature ====
|
||||
|
||||
You can use__ fortune__ to add a random signature to mutt.
|
||||
|
||||
$ pacman -S fortune-mod
|
||||
|
||||
Create a fortune file and then add the following line to your .muttrc:
|
||||
|
||||
**set signature="fortune pathtofortunefile"**
|
||||
|
||||
===== Viewing URLs & opening Firefox =====
|
||||
|
||||
Your should start by creating a **.mutt directory** in $HOME if not done yet. There, create a file named** macros**. Insert the following:
|
||||
|
||||
macro pager \cb <pipe-entry>'urlview'<enter> 'Follow links with urlview'
|
||||
|
||||
Then install __urlview__ with:
|
||||
|
||||
pacman -S urlview
|
||||
|
||||
Create a **.urlview** in $HOME and insert the following:
|
||||
|
||||
REGEXP (((http|https|ftp|gopher)|mailto)[.:][^ >"\t]*|www\.[-a-z0-9.]+)[^ .,;\t>">\):]
|
||||
COMMAND firefox %s
|
||||
|
||||
When you read an email on the pager, hitting__ ctrl+b__ will list all the urls from the email. Navigate up or down with arrow keys and hit enter on the desired url.** Firefox **will start and go to the selected site.
|
||||
|
||||
* Note - urlview has been moved to unsupported and is available in AUR here[1]
|
||||
* Note - If you have some problems with urlview due to Mutt's url encoding you can try extract_url.pl
|
||||
* Note - If you would like to see a short contextual preview of the content around each URL, try urlscan. The macro in your muttrc is the same as for urlview (except for the '**urlscan**' command). There is no additional configuration required other than ensuring $BROWSER is set.
|
||||
|
||||
===== Mutt and Vim =====
|
||||
|
||||
To limit the __width of text to 72 characters__, edit your .vimrc file and add:
|
||||
|
||||
au BufRead /tmp/mutt-* set tw=72
|
||||
|
||||
Another choice is to use Vim's mail filetype plugin to enable other mail-centric options besides 72 character width. Edit ~/.vim/filetype.vim, creating it if unpresent, and add:
|
||||
|
||||
|
||||
augroup filetypedetect
|
||||
" Mail
|
||||
autocmd BufRead,BufNewFile *mutt-* setfiletype mail
|
||||
augroup END
|
||||
|
||||
To set a different tmp directory, e.g. ~/.tmp, add a line to your muttrc as follows:
|
||||
|
||||
set tmpdir="~/.tmp"
|
||||
|
||||
To reformat a modified text see the Vim context help
|
||||
|
||||
:h 10.7
|
||||
|
||||
===== Viewing HTML within a Vim/Mutt setup =====
|
||||
|
||||
It is possible to pass the __html body __**to an external HTML program** and then__ dump__ it, keeping email viewing uniform and unobtrusive. Two programs are described here: **lynx and w3m**.
|
||||
|
||||
Install lynx or w3m:
|
||||
|
||||
pacman -S lynx
|
||||
or
|
||||
pacman -S w3m
|
||||
|
||||
If ~/.mutt/mailcap does not exist you will need to create it and save the following to it.
|
||||
|
||||
text/html; lynx -dump %s; nametemplate=%s.html; copiousoutput
|
||||
|
||||
or, in case of w3m,
|
||||
|
||||
text/html; w3m -I %{charset} -T text/html; copiousoutput;
|
||||
|
||||
Edit muttrc and add the following,
|
||||
|
||||
set mailcap_path = ~/.mutt/mailcap
|
||||
|
||||
To automatically open HTML messages in lynx, add this additional line to the muttrc:
|
||||
|
||||
auto_view text/html
|
||||
|
||||
The beauty of this is, instead of seeing an html body as source or being opened by a separate program, in this case lynx, it gets parsed to Vim as html, any url links within the email can be displayed with Ctrl+b.
|
||||
Mutt and GNU nano
|
||||
|
||||
nano is another nice console editor to use with Mutt.
|
||||
|
||||
To limit the width of text to 72 characters, edit your .nanorc file and add:
|
||||
|
||||
set fill 72
|
||||
|
||||
Also, in muttrc file, you can specify the line to start editing so that you will skip the mail header:
|
||||
|
||||
set editor="nano +7"
|
||||
|
||||
Colors
|
||||
|
||||
Append sample color definitions to your .muttrc file:
|
||||
|
||||
$ cat /usr/share/doc/mutt/samples/colors.linux >> ~/.muttrc
|
||||
|
||||
Then adjust to your liking. The actual color each of these settings will produce depends on the colors set in your ~/.Xresources file.
|
||||
Tips & Tricks
|
||||
Use Mutt to send mail from command line
|
||||
|
||||
Man pages will show all available commands and how to use them, but here are a couple of examples. You could use Mutt to send alerts, logs or some other system information, triggered by login through .bash_profile, or as a regular cron job.
|
||||
|
||||
Send a message:
|
||||
|
||||
mutt -s "Subject" somejoeorjane@someserver.com < /var/log/somelog
|
||||
|
||||
Send a message with attachment:
|
||||
|
||||
mutt -s "Subject" somejoeorjane@someserver.com -a somefile < /tmp/sometext.txt
|
||||
|
||||
How to display another email while composing
|
||||
|
||||
A common complaint with Mutt is that when composing a new mail (or reply), you cannot open another mail (i.e. for checking with another correspondent) without closing the current mail (postponing). The following describes a solution:
|
||||
|
||||
First, fire up Mutt as usual. Then, launch another terminal window. Now start a new Mutt with
|
||||
|
||||
mutt -R
|
||||
|
||||
This starts Mutt in read-only mode, and you can browse other emails at your convenience. It is strongly recommended to always launch a second Mutt in read-only mode, as conflicts will easily arise otherwise.
|
||||
|
||||
Now, this solution calls for a bit of typing, so we would like to automate this. The following works with Awesome, in other WM's or DE's similar solutions are probably available: just google how to add a key binding, and make the desired key execute
|
||||
|
||||
$TERM -e mutt -R
|
||||
|
||||
where $TERM is your terminal.
|
||||
|
||||
As for Awesome: edit your rc.lua, and add the following on one of the first lines, after terminal = "yourTerminal" etc.
|
||||
|
||||
mailview = terminal .. " -e mutt -R"
|
||||
|
||||
This automatically uses your preferred terminal, ".." is concatenation in Lua. Note the space before -e.
|
||||
|
||||
Then add the following inside --{{{ Key bindings
|
||||
|
||||
awful.key({ modkey, }, "m", function() awful.util.spawn(mailview) end),
|
||||
|
||||
Omit the final comma if this is the last line. You can, of course use another key than "m". Now, save&quit, and check your syntax with
|
||||
|
||||
awesome -k
|
||||
|
||||
If this is good, restart awesome and give it a try!
|
||||
|
||||
Now, a usage example: Launch mutt as usual. Start a new mail, and then press "Mod4"+"m". This opens your mailbox in a new terminal, and you can browse around and read other emails. Now, a neat bonus: exit this read-only-Mutt with "q", and the terminal window it created disappears!
|
||||
Additional resources
|
||||
|
||||
The official Mutt website
|
||||
The Mutt wiki
|
||||
Brisbin's great guide on how to setup different IMAP accounts with mutt + offlineimap + msmtp
|
||||
Documentation on Configuring Getmail with rcfiles
|
||||
75
Zim/Utils/Mutt/Gmail的IMAP和Mutt.txt
Normal file
@@ -0,0 +1,75 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-29T13:12:18+08:00
|
||||
|
||||
====== Gmail的IMAP和Mutt ======
|
||||
Created Thursday 29 December 2011
|
||||
http://www.adamjiang.com/archives/891
|
||||
Posted by jcadam - 27/08/10 at 12:08 下午
|
||||
|
||||
今天我想说的还是Mutt的问题。一年以前我写了通过mutt使用gmail。现在再回头看这篇文章的内容已经有些老旧了,只好在感慨时光如梭的同时附上更新。电子邮件对我来说越来越重,相应的Mutt这个邮件客户端也是如此。就像Mutt的作者说的,所有的邮件客户端都很烂,只是Mutt烂的不那么厉害罢了。我希望这几篇文章有用。
|
||||
|
||||
之前的解决方法相当复杂,需要mutt, procmail, fetchmail和msmtp等等工具的配合,配置起来非常繁琐。使用了很久这个方法之后,我发现还是**使用IMAP直接远程接入**Gmail比较简便。但是也有相应的缺点,那就是,使用IMAP的话,你就不能在离线状态中使用mutt了。
|
||||
|
||||
配置Gmail的IMAP和Mutt一起工作,相比用fetchmail去pop3服务器上的邮件,这个方法主要更改以下几点:
|
||||
|
||||
* 配置Gmail的IMAP
|
||||
* 设置远程服务器上的文件夹
|
||||
* 设置本地计算机上的缓冲
|
||||
* 设置远程服务器上的smtp服务
|
||||
|
||||
至于,邮件别名,色彩,和快捷键绑定等等,跟之前介绍的方法并无二致。
|
||||
|
||||
===== 配置Gmail的IMAP =====
|
||||
创建或者修改~/.muttrc,
|
||||
|
||||
vi ~/.muttrc
|
||||
|
||||
添加如下几行来告诉mutt你是谁,这里设置的姓名和邮件地址将出现在你的邮件的头部;
|
||||
|
||||
set from = "yourusername@gmail.com"
|
||||
set realname = "yourname"
|
||||
|
||||
接着,告诉mutt你Gmail邮箱和密码;
|
||||
|
||||
set imap_user = "yourusername@gmail.com"
|
||||
set imap_pass = "yourpassword"
|
||||
|
||||
在初次启动mutt的时候,mutt会询问你是否接受**认证文件**,你只需要回答”Yes”就可以了。
|
||||
|
||||
===== 设置远程服务器上的文件夹 =====
|
||||
Mutt可以**自动的识别IMAP服务器上的邮件文件夹**,所以这里其实不需要更多的动作。但是如果你想做一些自己的配置,可以采用下面的方法;
|
||||
|
||||
set folder = "imaps://imap.gmail.com:993"
|
||||
set spoolfile = "+INBOX"
|
||||
set postponed ="+[Gmail]/Drafts"
|
||||
set trash = "imaps://imap.gmail.com/[Gmail]/Trash"
|
||||
|
||||
===== 设置本地计算机上的缓冲 =====
|
||||
在本地计算机上,你需要一个缓冲来__保存文件头信息__,以及TLS证书等;
|
||||
|
||||
set header_cache =~/.mutt/cache/headers
|
||||
set message_cachedir =~/.mutt/cache/bodies
|
||||
set certificate_file =~/.mutt/certificates
|
||||
|
||||
别忘了创建相应的本地文件夹
|
||||
|
||||
mkdir -p ~/.mutt/cache
|
||||
|
||||
===== 设置远程服务器上的smtp服务 =====
|
||||
设置smtp服务器用来发送邮件
|
||||
|
||||
set smtp_url = "smtp://yourusername@smtp.gmail.com:587/"
|
||||
set smtp_pass = "yourpassword"
|
||||
|
||||
===== 其他设置 =====
|
||||
告诉Mutt不要将邮件移动的mbox里,同时为了增强安全性,设置连续上线时间不超过900分钟;
|
||||
|
||||
set move = no
|
||||
set imap_keepalive = 900
|
||||
|
||||
让mutt的配置文件成为“只读”属性。
|
||||
|
||||
chmod 700 .muttrc
|
||||
|
||||
配置结束。关于诸如色彩,快捷键,邮件编辑器等其他部分的配置,请参考我的mutt配置文件。
|
||||
6433
Zim/Utils/Mutt/Manual.txt
Normal file
201
Zim/Utils/Mutt/Manual/mutt的简单使用.txt
Normal file
@@ -0,0 +1,201 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-30T16:45:09+08:00
|
||||
|
||||
====== mutt的简单使用 ======
|
||||
Created Friday 30 December 2011
|
||||
http://hi.baidu.com/realasking/blog/item/10c1c3d346be6cd2a9ec9adc.html
|
||||
本文为原创内容,首发与百度linux吧和个人空间,如有转载,敬请注明出处与作者。
|
||||
——realasking
|
||||
|
||||
本系列前一篇帖子简介了如何使用fdm接收邮件,但是只能接收邮件是远远不够的,要
|
||||
在本地处理邮件,还需要邮件管理和发送的工具。在Linux/Unix系统下,mutt是最常
|
||||
用的邮件管理工具之一,功能非常强大,可以调用各种编辑器,以及邮件收、发工具,
|
||||
从而构成半自动/自动的邮件客户端,本文即初略介绍mutt的简单使用方法。
|
||||
|
||||
mutt的配置文件为.muttrc,在使用mutt之前,需要先建立该文件,但是该文件与fdm
|
||||
的配置文件不同,**没有很清晰的结构层次**,所有的变量和命令,都是只要存在,就会
|
||||
生效的,不过它的配置文件也因而具有更大的灵活性,在书写的时候,需要自己考虑
|
||||
需要实现的功能,以及__规划文件的结构__。
|
||||
|
||||
mutt的配置和写脚本文件有一些不太一样的地方,比如变量设定,在muttrc中使用的
|
||||
一部分变量,如邮件头my_hdr,mailboxes等,__新的设置并不会替换原有设置__,甚至
|
||||
会累加进去,而另有一些变量,如以set命令开头指定的,往往只**允许设置一次**,再如
|
||||
mutt有一些预先定义的action,即使在配置文件中没有进行指定,这些action在mutt
|
||||
启动之后也是有效的,还有就是可以用__宏__来自定义一些操作,此外,mutt可以定义地
|
||||
址列表和组,也支持直接保存发件人地址,而且提供了一系列的自动化的处理流程,
|
||||
即hook。所以,只要对需要使用mutt完成的操作有了解,那么就能通过采用mutt提供
|
||||
的这些功能来自由的组合和搭配,完成邮件的管理操作。
|
||||
|
||||
对于我自己来说,首先,我需要接收和处理多个邮箱的邮件,而且要能用这些邮箱分
|
||||
别发送和回复邮件,然后,考虑到我收发的邮件主要是中文邮件,因此中英文邮件不
|
||||
能有乱码,第三,我需要定义地址簿,第四,**要接收邮件列表**,第五,**要能接收rss**,
|
||||
第六,我习惯使用vi编辑器,邮件要按照主题和最后发送时间来排列。就这六条,对
|
||||
我来说应该基本够用,因此,加上界面设置,我一共将配置文件分为__六个部分__:
|
||||
a.通用设置
|
||||
b.宏定义
|
||||
c.邮件地址
|
||||
d.邮件列表
|
||||
e.电子邮件发送的定义
|
||||
f.界面设置
|
||||
|
||||
每个部分分别存成一个文件,然后用source命令包含进我的.muttrc文件中,这样,
|
||||
我的mutt配置文件内容就只有以下内容:
|
||||
|
||||
#通用
|
||||
source ~/.mutt/mu.general
|
||||
#宏
|
||||
source ~/.mutt/mu.macros
|
||||
#邮件地址
|
||||
source ~/mail/addressbook
|
||||
set alias_file=~/mail/addressbook
|
||||
#邮件列表
|
||||
source ~/.mutt/mlist
|
||||
#界面设置
|
||||
source ~/.mutt/mu.interface
|
||||
#邮件发送设置
|
||||
source ~/.mutt/mu.mls
|
||||
|
||||
其中,a.通用设置包括三个部分,首先是**邮箱文件**的设置,假定有
|
||||
realasking#mdbbs.org、realasking#hotmail.com和locahost三个邮箱(
|
||||
下文中出现的邮箱地址,均用#代替了@,真正在文件中设置时应该用@):
|
||||
|
||||
set mbox_type=Maildir
|
||||
set __folder__=$HOME/mail
|
||||
set spoolfile=~/mail/INBOX
|
||||
set header_cache=~/.hcache
|
||||
set mbox =__+__INBOX
|
||||
mailboxes "+INBOX"
|
||||
mailboxes "+realasking"
|
||||
mailboxes "+Hot"
|
||||
mailboxes "+localhost"
|
||||
只有用mailboxes添加的邮箱文件,才会**被mutt监控**,否则虽然可以用mutt读取邮件,
|
||||
但是却无法用其**监控新邮件**。
|
||||
|
||||
然后是本地化的设置,包括终端使用的编码,邮件编码,以及接收邮件的编码,并且
|
||||
解决编码中的乱码问题[1,2]:
|
||||
|
||||
set charset="UTF-8" #终端编码
|
||||
set send_charset="gb2312" #这里也可以设置为UTF-8
|
||||
set locale="zh_CN.UTF-8"
|
||||
set assumed_charset="gb2312" #对没有指明编码的邮件假设为gb2312
|
||||
charset-hook ^us-ascii$ gb2312 #这两行是对不正常的编码映射到gb2312
|
||||
charset-hook !UTF-8 gb2312
|
||||
set rfc2047_parameters=yes
|
||||
set copy=yes #这两行保存已经发送的邮件
|
||||
set record=~/mail/Sent
|
||||
set check_new=yes #检查新邮件
|
||||
auto_view text/html #自动阅读附件中的text/html
|
||||
set mime_forward_decode=yes
|
||||
|
||||
|
||||
第三部分是邮件的管理和编辑设置:
|
||||
|
||||
set editor="vim" #用vim作为默认编辑器
|
||||
set sort=threads #这两行是邮件排序方法
|
||||
set sort_aux=reverse-last-date-sent
|
||||
set pager_stop #这几行是邮件显示的方式,忘了从哪里抄过来的了
|
||||
set fast_reply
|
||||
set pager_index_lines=10
|
||||
set index_format="| %4C | %Z | %{%b %d} | %-15.15L | %s"
|
||||
set folder_format="| %2C | %t %N | %8s | %d | %f"
|
||||
#以下一行,用以让mutt显示回执相关的文件头,因为mutt默认是不支持邮件回执的
|
||||
#,所以它会隐藏这些信息,unignore的作用就是打开邮件头中被隐藏的相应的字段
|
||||
unignore disposition-notification-to return-receipt-to x-confirm-reading-to
|
||||
set header=no #回复邮件不加入原始邮件头
|
||||
|
||||
b.宏设置,宏设置是为了定义一连串的操作而存在的,可以用它来定义快捷键以调用
|
||||
外部的程序,或者mutt的相应功能,我的配置文件中这块比较简单,只有两句话,分
|
||||
别按G键调用fdm接收邮件,和按H键调用rss2email接收Rss:
|
||||
|
||||
macro index H "!r2e run"
|
||||
macro index G "!fdm -v fetch"
|
||||
|
||||
c.邮件地址簿,我定义为文件~/mail/addressbook,这是一个文本文件,其格式是:
|
||||
|
||||
alias 姓名 别名 <邮件地址>
|
||||
|
||||
然后一条一行往下排列即可,也应把权限设为600.
|
||||
|
||||
d.邮件列表,我定义为文件~/.mutt/mlist,这也是一个文本文件,格式是:
|
||||
|
||||
subscribe 邮件列表地址
|
||||
|
||||
e.电子邮件发送定义,这里,我定义为文件~/.mutt/mu.mls,其包括两个部分,第一
|
||||
部分是设置默认的发件和回邮的邮箱,第二个部分则是根据所进入的邮箱不同,自动
|
||||
source不同的设置,采用不同的邮箱来回复和发送邮件,这一部分大量使用hook,具
|
||||
体含义可以参考mutt的手册[3]。
|
||||
|
||||
其中第一部分是这样设置的:
|
||||
|
||||
#取消已有定义
|
||||
unmy_hdr from: #from是发送邮件的地址
|
||||
unmy_hdr Disposition-Notification-To: #这是回执请求的信息
|
||||
unmy_hdr X-Priority: #优先级的信息
|
||||
unmy_hdr reply-to: #回复到地址
|
||||
|
||||
send-hook . 'my_hdr from:realasking#mdbbs.org' #设置邮件头的发送邮件地址
|
||||
send-hook . 'my_hdr Disposition-Notification-To:realasking#mdbbs.org' #设置邮件回执请求
|
||||
send-hook . 'my_hdr X-Priority: 1' #设置邮件优先级为最高,优先级设置,1最高,3最低
|
||||
send-hook . 'set sendmail="/usr/bin/msmtp"' #这里使用msmtp发送邮件
|
||||
reply-hook . 'my_hdr reply-to:realasking#mdbbs.org'#这三行,是
|
||||
reply-hook . 'my_hdr Disposition-Notification-To:realasking#mdbbs.org'
|
||||
reply-hook . 'my_hdr X-Priority: 1'
|
||||
|
||||
第二部分是这样设置的:
|
||||
|
||||
folder-hook =realasking source ~/.mutt/realasking
|
||||
folder-hook =Hot source ~/.mutt/Hot
|
||||
|
||||
这里表示当用mutt进入邮箱realasking时,则自动读取配置文件~/.mutt/realasking,
|
||||
而进入Hot时,也类似,因此,用这种办法,就可以实现在不同的邮箱,用不同邮箱
|
||||
地址发信,下面是Hot文件中的设置:
|
||||
|
||||
unmy_hdr from:
|
||||
unmy_hdr Disposition-Notification-To:
|
||||
unmy_hdr X-Priority:
|
||||
unmy_hdr reply-to:
|
||||
send-hook . 'my_hdr from:realasking#hot.com'
|
||||
send-hook . 'my_hdr Disposition-Notification-To:realasking#hot.com'
|
||||
send-hook . 'my_hdr X-Priority: 1'
|
||||
send-hook . 'set sendmail="/usr/bin/msmtp -a Hot"'
|
||||
reply-hook . 'my_hdr reply-to:realasking#hot.com'
|
||||
reply-hook . 'my_hdr Disposition-Notification-To:realasking#hot.com'
|
||||
reply-hook . 'my_hdr X-Priority: 1'
|
||||
|
||||
对于请求回执和优先级设置,网上也有人提供了另一种方案,即直接在mutt里打补
|
||||
丁,而不需要向上面这样手动的写入邮件头定义,有兴趣的可以参考参考链接[4],
|
||||
而要想查看邮件头里写了些什么,在mutt中其实只需要按e键就可以看到。
|
||||
|
||||
另外,可以注意到,我这里每一封发出或者转发的邮件都要求已读提醒和高优先级,
|
||||
这样做也不是太合理,其实,如果要在需要时才设置这几个部分,只需要将它们设
|
||||
置为特定的宏即可,也不困难,同样的,也可实现发送邮件回执的功能。
|
||||
|
||||
f.也是最后一部分,是mutt的界面设置,用color命令即可,下面是几个例子,命令
|
||||
可以设置的内容和具体方法最好查询手册:
|
||||
|
||||
color normal blue black #mutt界面的主色调,黑底,蓝字
|
||||
color signature cyan black #签名档,黑底,青色
|
||||
color header brightred black ^Disposition-Notification-To:
|
||||
#请求回执高亮显示,黑底,红色
|
||||
color index red blue ~N #新邮件,蓝底,红色
|
||||
|
||||
配置完成之后,就可以用命令运行mutt了,启动mutt后,显示的最上面一行,提示
|
||||
的是常用的按键和对应的操作,最下面一行是提示的所在的邮箱文件和包括了多少
|
||||
邮件,中间就是收到的邮件,可以用方向键选择,按回车阅读。要写新邮件,则按
|
||||
m键,此时会提示To:,要求输入收件人地址,可以按Tab键从地址簿里选择,写完
|
||||
邮件并保存后,按y键可以发送邮件,而按a键添加附件;要接收邮件,则按G键,然
|
||||
后回车,接收之后按c键再选择邮箱以阅读邮件;如果要回复邮件,则是在阅读邮件
|
||||
或者选中邮件的状态按r键;如果要带附件转发邮件,稍微麻烦一点,我们需要按
|
||||
如下操作:
|
||||
打开邮件->按v->按t选择要转发的附件->按分号;和f键->按Tab键选择地址->修改
|
||||
->保存、发送
|
||||
|
||||
这就是mutt的基本使用方法,但是经过这样的配置,其实还不能发邮件和收rss,
|
||||
因为还需要配置msmtp和rss2email,本系列的下一篇帖子即讲述它们的简单用法。
|
||||
|
||||
参考链接:
|
||||
[1]http://www.kreny.com/docs/mutt.htm
|
||||
[2]http://hi.baidu.com/darkblueriver/blog/item/4368f50f10f3452e6059f350.html
|
||||
[3]http://www.mutt.org/#doc
|
||||
[4]http://www.mail-archive.com/mutt-dev@mutt.org/msg02399.html
|
||||
583
Zim/Utils/Mutt/Mutt_email_程序使用入门.txt
Normal file
@@ -0,0 +1,583 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-29T11:15:49+08:00
|
||||
|
||||
====== Mutt email 程序使用入门 ======
|
||||
Created Thursday 29 December 2011
|
||||
http://www.kreny.com/docs/mutt.htm
|
||||
|
||||
"All mail clients suck. This one just sucks less." -me, circa 1995
|
||||
|
||||
你也许听说过这句话?这不是危言耸听,我还没有遇到一个令我满意的 email 程序,直到我遇到 mutt。它不是图形界面的,但是它非常强大和方便。我曾经把它忽略,但是后来我发现其它 email 程序都有某种我不喜欢的怪毛病。最后我选择了 Mutt。
|
||||
|
||||
有人说 Gnus 才是最好的 email 客户端,可是 Gnus 要达到 Mutt 这种效果和方便程度,你需要付出太多代价。所以我宁愿使用 Mutt 调用 Emacs 来编辑 email 而不愿把 Gnus 配置来处理 email.
|
||||
|
||||
===== Mutt 的特点 =====
|
||||
|
||||
mutt 具有以下特点:
|
||||
|
||||
* 超强的信件分类功能
|
||||
你可以设置几乎任意的条件来从一堆信件里找到你所需要的那封。比如,你可以说:“只显示一个月之类,不是清华大学发来的,内容包含‘光盘’两个字的信件”,“把从 fvwm 邮件列表一个星期以前发来的,而且还没有看过的信件全部移到叫 old-fvwm 的信箱”……
|
||||
* 信件打分排序功能
|
||||
你可以给你的信件打分,比如我说:
|
||||
* 主题包含 "Circulation Notices" 的 +3 分。否则小心被图书馆罚款 :P
|
||||
* 从我爸爸发来的信件 +2 分。听爸爸话……
|
||||
* 主题包含"通知"两个字 +2 分。随时听取党中央号召 :)
|
||||
* 主题包含"believe me", "believe.*dream", "win.*free" 字样的, -1 分。这些一般都是广告。
|
||||
* 新的信件 +4 分。新的应该最先看。
|
||||
* 新的而上次忘了读的信件(old), +1 分。可能太忙了上次忘了看的信,这次应该先看。
|
||||
|
||||
* 信件最后的得分就是它的这些**分数相加**的结果。这样处理之后,你最想看的信件肯定就在最上面了。
|
||||
* 几乎任意条件的彩色设置
|
||||
* {{./mutt-color.png}}
|
||||
|
||||
* 可以随意绑定热键
|
||||
|
||||
这个功能类似 Emacs。你可以把几乎任意的功能绑定到键盘。你可以让 Mutt 的行为变成你喜欢的编辑器。比如我习惯了 VIM 的控制方式,我就把 "gg" 绑定到 "first-entry", 把 "G" 绑定到 "last-entry", 把 "Ctrl-F" 绑定到 next-page, 把 "Ctrl-B" 绑定到 previous-page.
|
||||
* 设置条件挂钩
|
||||
|
||||
你可以对**满足不同条件的信件,信箱采取不同的设置**。比如,对于用来收邮件的那些信箱,显示邮件时只显示 from, date, subject, x-mailer 这几个邮件头,而对 sent-mail 信箱还显示 to 这个邮件头;发给我家人,朋友的信件都存到一个特别的信箱中保存。
|
||||
* 批量邮件处理
|
||||
|
||||
你可以把一些**邮件作上标记**(tag),然后对它们进行**统一操作**,比如删除,存到其它文件,删除附件,……
|
||||
* 任选编辑器
|
||||
|
||||
用一个强大的编辑器来编辑你的 email 你才能高效的完成编辑。一般 email 客户端都是用的自己**内嵌的编辑器**,这些编辑器一般功能很弱。mutt 并没有试图自己写一个编辑器,因为它明显不可能超过 VIM 和 Emacs, 所以 mutt 可以让你自己选择你喜欢的编辑器,它会去调用它,并且设置很多方便编辑 email 的参数。编辑器编辑完毕后 mutt 会从编辑器得到编辑好的文本,然后你可以加附件什么的。我现在在 mutt 里使用 Emacs 编辑器。
|
||||
* 高级的 MIME 支持
|
||||
|
||||
Mutt 不像一般的 email 程序那样直接支持打开某些种类的附件。因为附件的种类实在太多,一个 email 客户端没有可能自己实现所有的功能。所以 Mutt 提供了__ .mailcap__ 的设置。你可以启用你**最喜欢的程序来打开某种特定类型的附件**。比如,我可以让 lynx 帮我把含有 HTML 附件的信件都转成文本在 Mutt 里显示,我让 ImageMagick 的 display 程序帮我显示图片……
|
||||
* 支持PGP加密
|
||||
|
||||
Mutt 可以利用 GnuPG 这样的程序来对信件进行 PGP **加密和数字签名**。别人可以用你的公用密钥给你发一封只有你才能看到的信件。你也可以用你的私有密钥给信件“签名”,收到信的人可以用你公布的公钥验证这封信确实是你发出来的。
|
||||
* Mutt是免费的
|
||||
|
||||
听了上面那么多好处之后,还有比这更好的消息吗?
|
||||
|
||||
==== Mutt 到哪里去找? ====
|
||||
|
||||
Mutt 的主页在 http://www.mutt.org/%E3%80%82%E4%B8%8A%E9%9D%A2%E6%9C%89%E6%89%80%E6%9C%89%E6%BA%90%E7%A8%8B%E5%BA%8F%E5%92%8C%E8%AF%B4%E6%98%8E%E6%96%87%E6%A1%A3。
|
||||
|
||||
==== Mutt 跟其它 email 程序有什么重大区别吗? ====
|
||||
|
||||
Mutt 显然是一个 __Unix 的邮件程序__,它跟一般的 Windows 邮件程序不同,它不是一个包罗万象的大杂烩。你甚至会发现它根本不直接发出邮件,它从来不自己编辑邮件,它从来不自己对邮件进行加密和数字签名……
|
||||
|
||||
Mutt 更像一个**文件管理器**,只不过它管理的是email。它的功能是借助各个最强大的程序来实现的。这符合 UNIX 的设计思想。
|
||||
|
||||
* 当 Mutt 需要编辑邮件时,它有可能调用 Emacs, vi, VIM, pico, ……等编辑器。
|
||||
* 当 Mutt 需要发信时,它把需要发出的信件放到 sendmail 的队列里,就什么都不管了。
|
||||
* 当需要数字签名时,Mutt 会把信件交给 GnuPG 之类的程序处理一下,然后再发出去。
|
||||
* 怎么收邮件呢?Mutt 不会自己到 POP 服务器去取邮件,你需要一个 fetchmail 程序,帮你把 email 从 POP 服务器取回来,转发到自己的 sendmail 的邮箱里。这样看起来就是你的主机成为了一个完整的 UNIX 网络工作站。
|
||||
|
||||
是不是觉得挺麻烦?其实有些 patch 可以使 Mutt 不依赖于这些程序,而自己处理收发工作。但是,强烈建议你使用这些外部程序!到时候你就知道这些东西的好处了。首先,VIM, sendmail, fetchmail 这些程序都是经过__千锤百炼__的质量信得过的程序,用它们编辑,发送,收取邮件你绝对放心。其次,你得到了一个 UNIX 网络工作站的功能:
|
||||
|
||||
* sendmail 不但可以帮 Mutt 发出邮件,也可以帮**其它 Unix 程序比如 tin 发送邮件**。如果你需要一个邮件服务器帮你中转,那么你只需要设置一次就可以使所有的用户的所有这样的程序都自动可以发送邮件,不用每个程序都去设置帐号了。
|
||||
* fetchmail 收到邮件之后会__转发__给本地的 sendmail. sendmail 如果允许 .forward, 你就可以在自己的目录里编辑一个 .forward 文件,信件可以自动被转发到其它地方或者经过一个过滤器过滤。你可以自己用perl等语言来写一个过滤器,它可以根据信件内容实现很多功能,比如自动回复等等。比如我就写了一个简单的过滤器,它可以记录所有发件人的地址,如果我把 helloooo 机器人连接到过滤器,恐怕你们就会收到可爱的 helloooo 的回信了 :)
|
||||
|
||||
===== Mutt 使用指南 =====
|
||||
|
||||
Mutt 的用法类似 VIM。你的__每一个键都是一个命令__,你可以在配置文件~/.muttrc设置很多选项来改变 Mutt 的行为。我没有太多时间写一个入门的介绍。你可以自己看看 Mutt Manual。我下面只解决一些中国人用 Mutt 常常遇到的问题。
|
||||
|
||||
===== 基本配置 =====
|
||||
|
||||
你一开始看到 Mutt 说明书上说的配置方法可能不知所措。现在我把你开始用的时候需要的一些必要的配置说一下。
|
||||
|
||||
alternates
|
||||
|
||||
这个变量应该设置为一个正则表达式,它是你有可能收到信件的地址。比如我的很简单,只有一个地址:
|
||||
|
||||
set alternates="wang-y01@mails.tsinghua.edu.cn"
|
||||
|
||||
这个变量有助于 Mutt 显示邮件的__地址特征__。一般 Mutt 会在index中显示几种不同的邮件地址特征,它们是由 $to_chars 变量指定的。
|
||||
to_chars
|
||||
|
||||
一般 $to_chars 的定义为 " +TCFL".
|
||||
" "(空): 表示这封邮件不是给你的,也就是说 To: 和 Cc: Bcc: 都没有你的地址,很多转发的邮件,未确认的邮件列表邮件,垃圾邮件都有这个特征。
|
||||
__+__: 表示你是收件人(To: 是你的地址之一),而且是唯一的收件人。
|
||||
T: 表示你是收件人(To: 包括了你的地址之一),但是你__不是唯一__的收件人。这是一封群体信件。
|
||||
C: 表示你的地址出现在 CC:,但是你不是唯一的被抄送的人。
|
||||
F: 表示这封邮件是你发出去的。
|
||||
L: 表示这是一封你已经加入的__邮件列表__寄来的。
|
||||
|
||||
你看看下面这幅图,就是mutt 有可能出现的一种列表,你看到地址特征没有?实际上地址特征出现在列表中的位置是可以改变的。待会儿在 $index_format 里你会看到的。
|
||||
|
||||
{{./mutt-to.png}}
|
||||
index_format
|
||||
|
||||
这是一个格式字符串,用来控制你的index的列表显示。它的缺省定义是:
|
||||
|
||||
set index_format="%4C %Z %{%b %d} %-15.15L (%4l) %s"
|
||||
|
||||
显示出来就是这个样子:
|
||||
{{./index-original.png}}
|
||||
|
||||
这里有一个简单的对应关系,%4C表示4位数的序号,%Z是__邮件状态__,你看到那个 __"r"__ 了吗?也就是说我已经回了这封信。%Z 还包含那个 "T", 也就是说这封信不只是寄给我一个人的,我爸爸每次寄信都会CC他自己一份 :) %{%b %d} 是__日期格式__,它是由 strftime() 函数的格式定义的。这里 %b 就是根据当前的 locale 设置的月份简称,“12月”。%d 就是十进制表示的每月的日号,“31”。后面的……你自己看看manual吧,我不罗嗦了。
|
||||
mailboxes
|
||||
|
||||
指定你有那些__信箱文件__。当你按 __"c"__ 切换信箱时,再按 Tab 键,这些信箱就可供你选择。
|
||||
|
||||
mailboxes Mailbox sent-mail
|
||||
|
||||
header
|
||||
|
||||
这是一个 bool 型变量。它表明你在回信时引用原文是否加入原文的邮件头。
|
||||
|
||||
set header=no
|
||||
|
||||
quit
|
||||
|
||||
{{./mutt-quit.png}}
|
||||
|
||||
可以设置为 yes, no, ask-yes, 或者 ask-no. 这是说,当你按q退出时,是否提示你(ask-yes,ask-no),还是直接就退出了(yes),还是根本不理你(no)。
|
||||
|
||||
set quit=ask-yes
|
||||
|
||||
auto_view
|
||||
|
||||
那些类型的附件是允许直接通过__ .mailcap 浏览__的?
|
||||
|
||||
auto_view text/html
|
||||
|
||||
move
|
||||
|
||||
这也是一个提示性变量。它是确定当你退出时,是否提示你把信件从 spool __移动到__的 mbox 文件。
|
||||
|
||||
set move=no
|
||||
|
||||
ascii_chars
|
||||
|
||||
当 Mutt 用 __thread 方式显示__时,是否用纯 ascii 表示树状列表。
|
||||
|
||||
set ascii_chars=yes
|
||||
|
||||
如果设置了就是这个样子:
|
||||
{{./mutt-ascii.png}}
|
||||
|
||||
include
|
||||
|
||||
回信时是否包含原文。
|
||||
|
||||
set include
|
||||
|
||||
indent_str
|
||||
|
||||
回信的引文之前插入那个符号?
|
||||
|
||||
set indent_str="> "
|
||||
|
||||
my_hdr
|
||||
|
||||
__设置你自己的邮件头__。比如我想让信件看上去是从 wang-y01@mails.tsinghua.edu.cn 发出的,而不是从 wy@wangyin.com 发出的。因为 wangyin.com 是我自己设置的主机名,不是注册的合法域名。我想让别人看到我的信是从我的清华信箱发出的,让他们直接回信到我的清华信箱,就这么干:
|
||||
|
||||
my_hdr From: wang-y01@mails.tsinghua.edu.cn
|
||||
|
||||
打分
|
||||
|
||||
新信件+4分,爸爸(w2r007)发来的 +2,主题包含“通知”的+2,主题包含 “Circulation” +3, 已经标记删除的 -5,上次没有读的 +1,包含 “believe”的 -10(垃圾广告!)。
|
||||
|
||||
score "~N" +4
|
||||
score "~f w2r007" +2
|
||||
score "~s 通知" +2
|
||||
score "~s Circulation" +3
|
||||
score "~D" -5
|
||||
score "~O" +1
|
||||
score "~s believe" -10
|
||||
|
||||
sort
|
||||
|
||||
排序方式。可以是
|
||||
|
||||
date
|
||||
date-sent
|
||||
date-received
|
||||
from
|
||||
mailbox-order (unsorted)
|
||||
score
|
||||
size
|
||||
subject
|
||||
threads
|
||||
to
|
||||
|
||||
几种方式,每种方式可以在前面加一个 "reverse-" 前缀表示反方向排序。我一般按分数排序:
|
||||
|
||||
set sort=score
|
||||
|
||||
sort_aux
|
||||
|
||||
当用 thread 排序方式时,我们对各个 thread 的相对排序顺序。
|
||||
|
||||
set sort_aux=date
|
||||
|
||||
pager_stop
|
||||
|
||||
如果设置,那么你在__pager__(就是你看信的内容的窗口里)翻页时,如果翻到最后,再按往下翻也不会翻到下一封信件。如果不设置就会自动翻到下一封信。
|
||||
|
||||
set pager_stop
|
||||
|
||||
fast_reply
|
||||
|
||||
如果设置,当你按 "r" 回信时,就不会再提示你输入回信地址和主题,直接进入编辑模式。
|
||||
|
||||
set fast_reply
|
||||
|
||||
resolve
|
||||
|
||||
当你按 "t" 或者 "D" 之类的标记操作时,是否自动把光标移动到下一封信件。
|
||||
|
||||
set resolve=yes
|
||||
|
||||
alias_file
|
||||
|
||||
当你在 index 里按 "a" 为来__信者取别名__时,使用哪一个别名文件保存这个别名。
|
||||
|
||||
set alias_file=/home/wy/.mutt.alias
|
||||
|
||||
__record__
|
||||
|
||||
你发出的邮件保存到那个信箱文件?比如可以像我这样每个月发出的信件放在不同的文件里。
|
||||
|
||||
set record="~/Mail/=sent-mail-`date +%Y-%m`"
|
||||
|
||||
charset
|
||||
|
||||
你的终端支持哪一种编码的显示?这个必须和你的终端编码一样。
|
||||
|
||||
set charset="gb2312"
|
||||
|
||||
send_charset
|
||||
|
||||
发信时可以使用的字符集。只有当前面的字符集不能正确表示信件内容时才会使用后面的。比如,如果你像下面这样设置,你的信件如果全是英文,那么信件就会被设置为 us-ascii 编码,如果出现了法语字符,那么就会用 iso-8859-1,如果出现了汉字就会用 gb2312,如果以上都不是,那么就用 utf-8。
|
||||
|
||||
set send_charset="us-ascii:iso-8859-1:gb2312:utf-8"
|
||||
|
||||
__wait_key__
|
||||
|
||||
当外部程序退出时,是否要求用户按一个键才返回。这在察看某些shell命令输出时是比要的,否则它们一下就消失了。
|
||||
|
||||
set wait_key=yes
|
||||
|
||||
confirmappend
|
||||
|
||||
当你要把信件存到另一个信箱,而这个信箱已经存在时,是否提示附加?
|
||||
|
||||
set noconfirmappend
|
||||
|
||||
edit_headers
|
||||
|
||||
是否把邮件头也放在编辑器里可以修改?
|
||||
|
||||
set edit_headers=no
|
||||
|
||||
pager_index_lines
|
||||
|
||||
当你在用 pager 看信件时,在 index 留出多少行显示邮件列表?
|
||||
|
||||
set pager_index_lines=4
|
||||
|
||||
比如我留下4行显示列表,其它的用来显示正文:
|
||||
{{./mutt-indexpager.png}}
|
||||
subscribe
|
||||
|
||||
告诉 Mutt 你已经订阅了那些邮件列表(mailing-list). 这有助于 Mutt 判断那些信件是邮件列表转过来的,避免你错误的回复到别人的私人信箱。也避免别人回复到你的私人信箱。
|
||||
|
||||
subscribe fvwm@fvwm.org
|
||||
|
||||
之后,收到的 To: 是 fvwm@fvwm.org 的信件看起来是这样:
|
||||
|
||||
{{./mutt-list.png}}
|
||||
|
||||
地址前面那个 "L" 表示这是一个邮件列表转过来的。你看到以后就不要按 "r" 回信,这样会回到别人的私人信箱去。按 "L",就可以回复到邮件列表地址,这里就是 fvwm@fvwm.org。
|
||||
|
||||
===== Mutt中文FAQ =====
|
||||
|
||||
以下是一些常见问题和解决方法。很多是我遇到的一些不能直接连接国外网络,没有自己的域名和邮件服务器的人遇到的问题。
|
||||
|
||||
怎样才能让我发出的信件使用我的POP邮箱的地址,而不是 root@myhost.com 这样的地址?
|
||||
|
||||
用 my_hdr 把你的 From: 设置为你想要的地址就行了。比如我是这样设置的:
|
||||
|
||||
my_hdr From: wang-y01@mails.tsinghua.edu.cn
|
||||
|
||||
注意 From: 的冒号之后有空格!
|
||||
怎样让 Mutt 显示日期等为中文?
|
||||
|
||||
__set locale__="zh_CN"
|
||||
|
||||
发出的信件为什么设置了错误的 charset?别人的程序不能正确显示我的中文信件!
|
||||
|
||||
把 gb2312 编码加到你的 send_charset. 就像这样最好:
|
||||
|
||||
set send_charset="us-ascii:iso-8859-1:gb2312:utf-8"
|
||||
|
||||
收到一些中文信件全部显示为 "???"
|
||||
|
||||
这是因为某些 email 客户端,比如清华大学 mails.tsinghua.edu.cn 的WWW界面客户端 没有设置字符编码,你看看邮件头(按h),是不是有个
|
||||
|
||||
Content-Type: text/plain
|
||||
|
||||
但是后面__没有说 charset=__"GB2312"? Mutt 遇到这种没有设置 charset 的邮件就会**使用 "us-ascii"**,所以如果你想让这种信件可以正确显示,就把 "us-ascii" 设置为 "gb2312" 的别名:
|
||||
|
||||
charset-hook ^us-ascii$ gb2312
|
||||
|
||||
注意 "us-ascii" 中间的连字号!
|
||||
可是仍然有邮件标题乱码呢!
|
||||
|
||||
看看你的 $spool 里那个乱码的信件是不是有类似如下内容:
|
||||
|
||||
Subject: =?iso8859-1?B?U29oddCj09HCvDq587Dg09DQwrPJ1LG808jro6E=?=
|
||||
|
||||
Chinaren 等服务器发出来的信件使用了 quoted-printable 的 subject,而且设置编码为 "iso8859-1",这显然是错误的。
|
||||
|
||||
对付这个错误的办法是把 iso-8859-1 变成 gb2312 的别名:
|
||||
|
||||
charset-hook ^iso-8859-1$ gb2312
|
||||
|
||||
注意 "iso-8859-1" 中间的连字号!
|
||||
|
||||
如果仍然有信件乱码。干脆用
|
||||
|
||||
charset-hook .* gb2312
|
||||
|
||||
把所有信件都用 gb2312 显示。
|
||||
可是这样设置之后 evolution 发过来的 subject 为 utf-8 编码的邮件标题乱码!
|
||||
|
||||
那就把不是 utf-8 的编码都映射到 gb2312:
|
||||
|
||||
__ charset-hook !utf-8 gb2312__
|
||||
|
||||
怎样配置 fetchmail?
|
||||
|
||||
fetchmail 的配置非常简单。如果只是一个人用的话,可以这样设置:比如,我在我的 $HOME 目录编辑了一个 .fetchmailrc:
|
||||
|
||||
set daemon 60
|
||||
poll mails.tsinghua.edu.cn
|
||||
protocol POP3
|
||||
user "wang-y01"
|
||||
password "wang-y01的密码"
|
||||
poll smth.org
|
||||
....
|
||||
....
|
||||
|
||||
然后把 fetchmail 写到我的shell启动脚本里:
|
||||
|
||||
! ps aux | grep -q fetchmail && fetchmail &
|
||||
|
||||
fetchmail 启动后成为一个 daemon, 每分种帮我检查所有邮箱里的邮件,收回来,并且转发到本地信箱。修改上面那个 "60" 就可以改变检查时间间隔。
|
||||
|
||||
如果不想让 fetchmail 删除服务器上的文件,而且每次只取新的信。就在配置文件里加上:
|
||||
|
||||
keep
|
||||
uidl
|
||||
|
||||
我不想用 fetchmail,能不能直接收回 POP 信件啊?
|
||||
|
||||
如果你的 Mutt 编译时加入了 POP 功能,那么你可以直接从 POP 服务器收邮件而不用借助于 fetchmail. 把类似这些行加入 ~/.muttrc
|
||||
|
||||
set pop_user=wang-y01
|
||||
set pop_pass="wang-y01的密码"
|
||||
set pop_host="pop://mails.tsinghua.edu.cn"
|
||||
|
||||
也可以一次性输入所有内容:
|
||||
|
||||
set pop_host="pop://wang-y01:wang-y01的密码@smth.org"
|
||||
|
||||
在 Mutt 里按一下 "G" 就可以取邮件了。
|
||||
怎样处理多个 POP3 信箱?
|
||||
|
||||
如果你有多个POP信箱,你可以设置一些方便的宏把POP信件收到你信箱里。举个例子,就像我这样:
|
||||
|
||||
__macro index ,shredder __":set pop_host=\
|
||||
\"pop://shredder:shredder的密码@smth.org\"\r\
|
||||
<fetch-mail>"
|
||||
|
||||
macro index ,sk8er ":set pop_host=\
|
||||
\"pop://sk8er:sk8er的密码@smth.org\"\r\
|
||||
<fetch-mail>"
|
||||
|
||||
macro index ,ts ":set pop_host=\
|
||||
\"pop://wang-y01:wang-y01的密码@mails.tsinghua.edu.cn\"\r\
|
||||
<fetch-mail>"
|
||||
|
||||
macro index ,g ",shredder,sk8er,ts"
|
||||
|
||||
这样,我只要按 ,shredder 就可以收我在 smth 上 shredder 的信件,只要按 ,sk8er 就可以收我在 smth 上 sk8er 的信件,只要按 ,ts 就可以收 mails.tsinghua.edu.cn 的信件,只要按 ,g 就可以收取我所有 POP 信箱的信件了。
|
||||
怎样直接访问 POP3 信箱?
|
||||
|
||||
除了上面的方法,你还可以直接访问 POP3 信箱。比如,我可以直接按 "c" 切换到信箱 pop://sk8er:sk8er的密码@smth.org
|
||||
|
||||
就可以浏览 pop 的信件了。切换到其它信箱就浏览不同的 pop。如果你嫌按键太多可以自己定义一个宏。这是同步操作,你如果在这个信箱里删除一封信件,mutt 就会删除你 pop3 服务器上的信件。你不删它也不删。
|
||||
|
||||
邮件太多时这样效率很低,每次都要取所有邮件头,就像 Foxmail 的“远程邮件管理”。所以最好在那种不想取回信件,而想直接删除垃圾邮件的时候用这个办法。
|
||||
怎样处理邮件列表?
|
||||
|
||||
参看subscribe命令。
|
||||
* 我按 "d" 的时候邮件被直接标记删除了,怎样才能__把删掉的信件都移到一个“垃圾箱”__呢?
|
||||
|
||||
你只要把信件用 save-message 函数保存到你的垃圾箱,比如 ~/Mail/Trash,信件会被自动做上 "D"(删除) 标志。为了让 "d" 可以保存到垃圾箱,你可以把 "d" 键绑定到一个 宏。但是如果你要删除垃圾箱里的邮件,这个宏会再次把垃圾箱的邮件存储到垃圾箱,产生循环。所以你应该使用 folder-hook 在垃圾箱里把 "d" 恢复到原来的 delete-message 函数,而在其它信箱使用那个宏。
|
||||
|
||||
现在你可以用以下设置得到一个“垃圾箱”的功能。第一次按 "d" 时有可能会被讯问是否建立这个信箱(Trash).
|
||||
|
||||
folder-hook . 'macro index d "~/Mail/Trash\r"'
|
||||
folder-hook ~/Mail/Trash 'bind index d delete-message'
|
||||
|
||||
* 当收到的邮件的 header 有很多项目时,我的 pager 里全都是邮件头。怎样才能只看到某些我想看的邮件头呢?
|
||||
|
||||
你可以__用 ignore 忽略你不想看到的邮件头__,如果 ignore *,你就可以忽略所有邮件头。用 unignore 可以恢复显示被忽略的邮件头。所以一个简单的办法就是先把所有邮件头忽略,然后放出你想看的那几个。
|
||||
|
||||
看下面的设置。我的 sent.*(发件箱) 里只显示 To: Subject: Date: 三项。而在其它信箱就显示 From: Subject: X-Mailer: Date: 这几项。
|
||||
|
||||
folder-hook . "ignore *; unignore from subject X-mailer date"
|
||||
folder-hook sent.* "ignore *; unignore to subject date"
|
||||
|
||||
你还可以指定邮件头显示的顺序:
|
||||
|
||||
hdr_order from to subject date
|
||||
|
||||
* Mutt 怎么使用地址簿呢?
|
||||
|
||||
你可以用 alias 来实现一个地址簿。alias 命令的形式是这样的,举个例子:
|
||||
|
||||
alias wy Wang Yin <wang-y01@mails.tsinghua.edu.cn>
|
||||
|
||||
alias 是命令,wy 是别名,Wang Yin <wang-y01@mails.tsinghua.edu.cn> 是一个标准的 email 地址。这样,如果你在 index 里按 "m",在 To: 的提示下输入 "wy",就可以发信给 Wang Yin <wang-y01@mails.tsinghua.edu.cn> 。
|
||||
|
||||
在 To: 的提示下按 Tab 就可以显示联系人列表,然后你可以移动光标选择联系人。
|
||||
|
||||
如果你有很多 alias 要写,最好把它们写到另外一个文件,比如叫 .mutt.alias. 然后在 .muttrc 里加上:
|
||||
|
||||
source ~/.mutt.alias
|
||||
|
||||
你还可以设置一个变量:
|
||||
|
||||
__set alias_file=~/.mutt.alias__
|
||||
|
||||
这样你在 index 里按 "a",就可以把来信人加入到这个 alias 文件了。
|
||||
* Mutt __如何处理 HTML 附件__?
|
||||
|
||||
Mutt 可以处理任何类型的附件。因为它可以调用合适的程序来处理它们。为了直接在 mutt 的窗口里显示 HTML,你只需要在 ~/.mailcap 文件加入:
|
||||
|
||||
text/html; lynx --dump %s; nametemplate=%s.html; copiousoutput
|
||||
|
||||
在 ~/.muttrc 加入:
|
||||
|
||||
auto_view text/html
|
||||
|
||||
* Mutt 如何处理 Word doc 附件。
|
||||
|
||||
清华大学总是喜欢发送含有 doc 附件的通知。真是让人ft。现在有一个完美的解决方案了:使用 wvware 把 doc 转成 HTML 嵌入mutt里。
|
||||
|
||||
wvware 可以在 http://www.wvware.com/%E5%85%8D%E8%B4%B9%E5%BE%97%E5%88%B0。
|
||||
|
||||
wvHtml --charset=gb2312 your.doc your.html
|
||||
|
||||
就可以把doc转成 HTML。经测试,能够正确处理汉字和图片。
|
||||
|
||||
你可以让mutt调用 wvHtml 在自己的窗口里直接显示转换的 doc 文档。只需要在 ~/.mailcap 文件加入:
|
||||
|
||||
application/msword; wvHtml --charset=gb2312 %s - | lynx --dump -stdin;
|
||||
nametemplate=%s.html; copiousoutput
|
||||
|
||||
text/html; lynx --dump %s; nametemplate=%s.html; copiousoutput
|
||||
|
||||
在 ~/.muttrc 加入:
|
||||
|
||||
auto_view text/html application/msword
|
||||
|
||||
这样你的 mutt 看一个 doc 的时候就像这个样子:
|
||||
mutt-wvware
|
||||
我想在 Mutt 里使用 Emacs 怎么办?
|
||||
|
||||
Emacs 是一个非常强大的编辑器,所以你肯定会希望能在 Mutt 里使用 Emacs。你可以选择两种方式:
|
||||
一种方式是直接在 Mutt 的终端里使用非图形界面的 Emacs (emacs -nw)。
|
||||
|
||||
你只需要在 .muttrc 设置:
|
||||
|
||||
set editor="emacs -nw"
|
||||
|
||||
这样会启动一个新的 Emacs。如果你的 Emacs 配置加入了大量扩展,这个启动时间是相当长的,你不希望每回一封email就等上10秒等Emacs启动吧?
|
||||
|
||||
有一个办法可以跳过冗长的 Emacs 扩展。只需要把你的 .emacs 里耗时的部分放在一个条件语句里。比如,我就把 desktop 和 session 放在了一个条件语句里启动。如果知道编辑的文件名叫做 "/tmp/mutt-..." 那我们就知道是 mutt 在调用 Emacs,所以我就不加载 desktop 和 session 这种费时间又没用的东西。
|
||||
|
||||
(unless
|
||||
(catch 'found
|
||||
(dolist (arg command-line-args)
|
||||
(if (string-match "^/tmp/mutt-" arg)
|
||||
(throw 'found t))))
|
||||
|
||||
;; load desktop
|
||||
(load "desktop")
|
||||
(desktop-load-default)
|
||||
(desktop-read)
|
||||
|
||||
;; load session
|
||||
(require 'session)
|
||||
(add-hook 'after-init-hook 'session-initialize)
|
||||
(setq desktop-globals-to-save '(desktop-missing-file-warning))
|
||||
|
||||
;; start server
|
||||
(server-start)
|
||||
)
|
||||
|
||||
一种方式是使用 emacsclient 发送到 GUI 的 Emacs 服务器编辑。
|
||||
|
||||
这种方式可以使用一个已经启动的 Emacs,启动非常快速。但是我不是很喜欢这种方式,因为我不想离开 Mutt 的终端到 Emacs 的窗口,编辑完了还要切换窗口。看这幅图。
|
||||
|
||||
先来看看 Emacs 的设置,启动 Emacs 后,你可以使用 server-start 启动 Emacs 服务器。你也可以把
|
||||
|
||||
(server-start)
|
||||
|
||||
加入到你的 .emacs 文件,这样 Emacs 启动时自动就启动了服务器。
|
||||
|
||||
在 .muttrc 里加入
|
||||
|
||||
set editor=emacsclient
|
||||
|
||||
这样 Mutt 在要发送邮件时,就把需要编辑的东西送到已经启动的 Emacs 里。编辑完了之后你按 C-x #,控制会转回到 Mutt.
|
||||
我不能直接连国外,sendmail必需通过 mails.tsinghua.edu.cn 转发,但是 sendmail 不能通过 ESMTP 验证怎么办?
|
||||
|
||||
由于清华大学网络中心的限制,一般同学不能直接连接国外的服务器。这样 sendmail 就不能直接将邮件发送到目的地。我们需要依赖国内的 邮件服务器来转发到目的地。但是现在国内的smtp邮件服务器通常需要 SMTP 验证才能帮你转发邮件。比如 mails.tsinghua.edu.cn, 这是一种防止别人利用自己主机发送垃圾邮件的办法。
|
||||
|
||||
sendmail 怎样才能通过 SMTP 身份验证呢?sendmail 的网页上说有办法。可是我搞了一天还是没有搞定。而且 sendmail 是以安全漏洞著称的。所以我决定换用 Postfix。qmail 也很好,但是我不知道怎么让 qmail 通过 AUTH SMTP 转发, 如果有人知道请告诉我。
|
||||
|
||||
postfix 是一个可以取代 sendmail 的邮件服务器。它在普通机器上可以达到 sendmail 3 倍的吞吐率。而且相当安全。它可以在 www.postfix.org 下载安装过程如下:
|
||||
编译的时候你需要让 postfix 支持 SASL 验证,使用以下选项编译:
|
||||
|
||||
% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
|
||||
AUXLIBS="-L/usr/local/lib -lsasl"
|
||||
|
||||
然后安装
|
||||
|
||||
% make; make install
|
||||
|
||||
为了 postfix 能够正确发送本地邮件,请在 /etc/postfix/main.cf 加上:
|
||||
|
||||
myhostname = tu140066.tsinghua.edu.cn
|
||||
mydestination = wangyin.com, $myhostname, localhost.$mydomain
|
||||
|
||||
$myhostname 指明了你的主机域名,清华大学的网络给了每个人一个域名,其实就是 tuxxxxxx.tsinghua.edu.cn, xxxxxx 就是你的 IP 后面的数字,比如我的IP是166.111.140.66, 所以我的域名是 tu140066.tsinghua.edu.cn.
|
||||
|
||||
$mydestination 指出哪些地址是认为是你自己的地址。你应该把你的机器名(我的是 wangyin.com),$myhostname, $localhost.$mydomain 加进去。
|
||||
为了能够使用 SASL 验证登录,把这些行加到 /etc/postfix/main.cf
|
||||
|
||||
smtp_sasl_auth_enable = yes
|
||||
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||
smtp_sasl_security_options =
|
||||
relayhost = mails.tsinghua.edu.cn
|
||||
|
||||
编辑口令文件 /etc/postfix/sasl_passwd。加入一行:
|
||||
|
||||
Your.Relay.Server your_auth_login_name:Your_PassWord
|
||||
|
||||
比如我的口令文件是这样的:
|
||||
|
||||
mails.tsinghua.edu.cn wang-y01:aDF2m@3d$q=+
|
||||
|
||||
当然密码不是那个 :P
|
||||
把口令文件转成 Berkeley DB 格式:
|
||||
|
||||
#postmap hash:sasl_passwd
|
||||
|
||||
启动你的 postfix 服务器
|
||||
|
||||
postfix start
|
||||
|
||||
Valid HTML 4.01!
|
||||
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/index-original.png
Normal file
|
After Width: | Height: | Size: 738 B |
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/mutt-ascii.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/mutt-color.png
Normal file
|
After Width: | Height: | Size: 440 KiB |
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/mutt-indexpager.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/mutt-list.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/mutt-quit.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
Zim/Utils/Mutt/Mutt_email_程序使用入门/mutt-to.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
450
Zim/Utils/Mutt/配置mutt做邮件客服端.txt
Normal file
@@ -0,0 +1,450 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-28T20:41:25+08:00
|
||||
|
||||
====== 配置mutt做邮件客服端 ======
|
||||
Created Wednesday 28 December 2011
|
||||
|
||||
http://home.ustc.edu.cn/~lixuebai/GNU/MuttConfig.html
|
||||
|
||||
我用的操作系统是Debian或者Ubuntu GNU/linux
|
||||
这里的组合是__mutt+msmtp+getmail+procmail__
|
||||
|
||||
mutt是作为客户端mua,msmtp是邮件发送mta,getmail收取邮件,procmail过滤邮件mda。
|
||||
|
||||
在Debian中默认安装的mta是**exim4**,在Ubuntu中默认安装的mta是**postfix**, 它们当然可以用,但是足够用于邮件服务器了,如果你是个人电脑使用,就不需要用这么好的mta了,况且exim4或者postfix占用系统资源很大,没有必要开机自动运行。
|
||||
|
||||
msmtp是为mutt写的,很简单轻便的. 另外,还有些人用esmtp等都可以。
|
||||
|
||||
收取邮件,从前大家都使用比较著名的fetchmail. fetchmail是收取信件,但不是直接放在本地硬盘中,而是需要本地mta投递,所以需要procmail
|
||||
|
||||
看到有人建议不用fetchmail,而是用getmail, 据说fetchmail问题太多,而getmail则没有那些问题,你可以在aptitude中看getmail4 包的介绍,就说是为了替代fetchmail的
|
||||
|
||||
作者为什么要写getmail的说明在 http://pyropus.ca/software/getmail/faq.html#faq-about-why
|
||||
|
||||
当然可能有人喜欢exim或者postfix,喜欢fetchmail,我会放在后面讲述。分别是MuttConfig:exim MuttConfig:postfix MuttConfig:fetchmailrc
|
||||
|
||||
现在我来说怎么配置
|
||||
mutt+msmtp+getmail+procmail
|
||||
|
||||
首先aptitude
|
||||
|
||||
可以先卸载exim4或者postfix,这时候会遇到其他包的关联问题,因为不存在mta了嘛,所以选中msmtp-mta
|
||||
|
||||
再选中msmtp,mutt,getmail4,procmail
|
||||
|
||||
再选中lynx(这是一个文本话浏览网页的工具),wv (wvware是用于把MS doc文档转化为html或者tex文档的工具), 这两个在后面配置mutt中用的着。
|
||||
建立文件箱
|
||||
|
||||
$ mkdir ~/Mail
|
||||
$ cd ~/Mail
|
||||
|
||||
新建三个文件
|
||||
|
||||
$ vim inbox
|
||||
$ vim sent
|
||||
$ vim postponed
|
||||
|
||||
空文件,存盘退出就可以了。
|
||||
配置mutt
|
||||
|
||||
新建~/.muttrc
|
||||
|
||||
# lixuebai
|
||||
|
||||
#编辑器 直接在 Mutt 的终端里使用非图形界面的 Emacs (emacs -nw)
|
||||
set editor="emacs -nw"
|
||||
|
||||
#设置邮件发送程序
|
||||
set sendmail="/usr/bin/msmtp"
|
||||
|
||||
#建立信箱
|
||||
set folder="~/Mail"
|
||||
set mbox="~/Mail/inbox"
|
||||
#set mbox_type=maildir
|
||||
set spoolfile="~/Mail/inbox"
|
||||
set postponed="~/Mail/postponed"
|
||||
set record="~/Mail/sent"
|
||||
|
||||
# 让mutt监视下面几个邮箱,并随时报告新邮件
|
||||
mailboxes "=inbox"
|
||||
mailboxes "=USTCstudent"
|
||||
mailboxes "=USTCteacher"
|
||||
mailboxes "=ustcbbs
|
||||
mailboxes "=Gmail"
|
||||
|
||||
set check_new = yes
|
||||
set timeout = 600
|
||||
|
||||
#set alternates="xxx@mail.ustc.edu.cn"
|
||||
#这是一个格式字符串,用来控制你的index的列表显示。它的缺省定义是
|
||||
|
||||
set index_format="%4C %Z %{%b %d} %-15.15L (%4l) %s"
|
||||
#指定你有那些信箱文件。当你按 "c" 切换信箱时,再按 Tab 键,这些信箱就可供你选择
|
||||
mailboxes Mailbox sent-mail
|
||||
#这是一个 bool 型变量。它表明你在回信时引用原文是否加入原文的邮件头。
|
||||
set header=no
|
||||
#可以设置为 yes, no, ask-yes, 或者 ask-no. 这是说,当你按q退出时,是否提示你(ask-yes,ask-no),
|
||||
#还是直接就退出了(yes),还是根本不理你(no)。
|
||||
set quit=ask-yes
|
||||
#html类型的附件是允许直接通过 .mailcap 浏览的?
|
||||
#doc类型的附件通过wvware转成html 浏览
|
||||
auto_view text/html application/msword
|
||||
|
||||
#这也是一个提示性变量。它是确定当你退出时,是否提示你把信件从 spool 移动到的 mbox 文件。
|
||||
set move=no
|
||||
#当 Mutt 用 thread 方式显示时,是否用纯 ascii 表示树状列表。
|
||||
set ascii_chars=yes
|
||||
#回信时是否包含原文。
|
||||
set include
|
||||
#回信的引文之前插入那个符号?
|
||||
set indent_str="> "
|
||||
#设置你自己的邮件头。
|
||||
my_hdr From: xxx@mail.ustc.edu.cn
|
||||
#打分
|
||||
#新信件+4分,主题包含“通知”的+2,主题包含 “Circulation” +3, 已经标记删除的 -5,上次没有读的 +1,包含 “believe”的 -10(垃圾广告!)。
|
||||
score "~N" +4
|
||||
score "~s 通知" +2
|
||||
score "~s Circulation" +3
|
||||
score "~D" -5
|
||||
score "~O" +1
|
||||
score "~s believe" -10
|
||||
#排序方式。
|
||||
set sort=score
|
||||
#当用 thread 排序方式时,我们对各个 thread 的相对排序顺序。
|
||||
set sort_aux=date
|
||||
#如果翻到最后,再按往下翻也不会翻到下一封信件
|
||||
set pager_stop
|
||||
#如果设置,当你按 "r" 回信时,就不会再提示你输入回信地址和主题,直接进入编辑模式。
|
||||
set fast_reply
|
||||
#当你按 "t" 或者 "D" 之类的标记操作时,是否自动把光标移动到下一封信件。
|
||||
set resolve=yes
|
||||
#地址簿
|
||||
source ~/.mutt.alias
|
||||
#当你在 index 里按 "a" 为来信者取别名时,使用哪一个别名文件保存这个别名。
|
||||
set alias_file=/home/lixuebai/.mutt.alias
|
||||
#你发出的邮件保存到那个信箱文件?比如可以像我这样每个月发出的信件放在不同的文件里。
|
||||
set record="~/Mail/=sent-mail-`date +%Y-%m`"
|
||||
#你的终端支持哪一种编码的显示?这个必须和你的终端编码一样。推荐用utf8
|
||||
set charset="utf8"
|
||||
#send_charset
|
||||
set send_charset="us-ascii:iso-8859-1:gb2312:utf-8"
|
||||
#外部程序退出时,是否要求用户按一个键才返回。这在察看某些shell命令输出时是比要的,
|
||||
#否则它们一下就消失了。
|
||||
set wait_key=yes
|
||||
#当你要把信件存到另一个信箱,而这个信箱已经存在时,是否提示附加?
|
||||
set noconfirmappend
|
||||
#是否把邮件头也放在编辑器里可以修改?
|
||||
set edit_headers=no
|
||||
#当你在用 pager 看信件时,在 index 留出多少行显示邮件列表?
|
||||
set pager_index_lines=4
|
||||
#告诉 Mutt 你已经订阅了那些邮件列表(mailing-list).
|
||||
#subscribe fvwm@fvwm.org
|
||||
|
||||
#mutt显示日期为中文
|
||||
set locale="zh_CN"
|
||||
#有些没有设置字符编码时
|
||||
charset-hook ^us-ascii$ gb2312
|
||||
#Chinaren 等服务器发出来的信件使用了 quoted-printable 的 subject,
|
||||
#而且设置编码为 "iso8859-1",这显然是错误的。
|
||||
#对付这个错误的办法是把 iso-8859-1 变成 gb2312 的别名
|
||||
charset-hook ^iso-8859-1$ gb2312
|
||||
# evolution 发过来的 subject 为 utf-8 编码的邮件标题乱码!
|
||||
#那就把不是 utf-8 的编码都映射到 gb2312
|
||||
charset-hook !utf-8 gb2312
|
||||
|
||||
# mutt进行pop3收信,当然之前要查看$ mutt -v 编辑情况的确编辑了pop3了。
|
||||
# 以后进入mutt按G就可以收信了。
|
||||
#set pop_user=xxx@mail.ustc.edu.cn
|
||||
#set pop_pass="xxxxxx"
|
||||
#set pop_host=202.38.64.8
|
||||
#现在不用mutt直接收信了。
|
||||
|
||||
#把mutt发送的from域作为sendmail发送邮件的sender(否则会用user@localdomian)
|
||||
set envelope_from=yes
|
||||
|
||||
macro index G "!getmail\n" "Invoke getmail"
|
||||
macro pager G "!getmail\n" "Invoke getmail"
|
||||
|
||||
配置msmtp
|
||||
|
||||
新建~/.msmtprc
|
||||
|
||||
# xxx@mail.ustc.edu.cn
|
||||
account xxx@mail.ustc.edu.cn
|
||||
host 202.38.64.8
|
||||
from xxx@mail.ustc.edu.cn
|
||||
auth plain
|
||||
user xxx@mail.ustc.edu.cn
|
||||
password xxxxxx
|
||||
|
||||
科大邮件服务器是采用明码密码的,所以有auth plain
|
||||
|
||||
注意一点,~/.msmtprc权限不能过高,
|
||||
|
||||
$ chmod -v 600 ~/.msmtprc
|
||||
|
||||
就可以了。
|
||||
配置getmail
|
||||
|
||||
新建文件夹~/.getmail/ 并在这个文件夹中新建文件getmailrc
|
||||
|
||||
$ mkdir ~/.getmail
|
||||
$ cd ~/.getmail/
|
||||
$ vim getmailrc
|
||||
|
||||
[options]
|
||||
verbose = 1
|
||||
read_all = false
|
||||
message_log = ~/.getmail/log
|
||||
|
||||
[retriever]
|
||||
type = SimplePOP3Retriever
|
||||
server = 202.38.64.8
|
||||
username = xxx@mail.ustc.edu.cn
|
||||
password = xxxxxx
|
||||
|
||||
[destination]
|
||||
type = MDA_external
|
||||
path = /usr/bin/procmail
|
||||
unixfrom = true
|
||||
|
||||
使用crontab定时自动收信
|
||||
|
||||
$ crontab -e
|
||||
|
||||
每隔10分钟收一次信,只收未读的信件。
|
||||
|
||||
0,10,20,30,40,50 * * * * getmail -n
|
||||
|
||||
配置procmail
|
||||
|
||||
新建文件~/.procmailrc
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin
|
||||
SHELL=/bin/bash
|
||||
MAILDIR=$HOME/Mail
|
||||
DEFAULT=$MAILDIR/inbox
|
||||
LOGFILE=$MAILDIR/.procmaillog
|
||||
|
||||
:0
|
||||
* ^From.*@mail.ustc.edu.cn
|
||||
USTCstudent
|
||||
|
||||
:0
|
||||
* ^From.*@ustc.edu.cn
|
||||
USTCteacher
|
||||
|
||||
:0
|
||||
* ^From.*@bbs.ustc.edu.cn
|
||||
ustcbbs
|
||||
|
||||
:0
|
||||
* ^From.*@gmail.com
|
||||
Gmail
|
||||
|
||||
:0 #最后的这个配置就是指如果上面分类剩下的信件全扔到inbox里
|
||||
* .* inbox
|
||||
|
||||
# 黑名单(垃圾邮件)
|
||||
:0:
|
||||
* ^From.*badguy
|
||||
/dev/null
|
||||
|
||||
下面说几个mutt其他方面的问题
|
||||
mutt使用地址簿
|
||||
|
||||
用 alias 来实现一个地址簿。alias 命令的形式是这样的,举个例子:
|
||||
|
||||
alias ab Xx X <xxx@mail.ustc.edu.cn>
|
||||
|
||||
alias 是命令,ab 是别名,Xx X <xxx@mail.ustc.edu.cn> 是一个标准的 email 地址。这样,如果你在 index 里按 "m",在 To: 的提示下输入 "ab",就可以发信给 Xx X <xxx@mail.ustc.edu.cn>。
|
||||
|
||||
在 To: 的提示下按 Tab 就可以显示联系人列表,然后你可以移动光标选择联系人。
|
||||
|
||||
如果你有很多 alias 要写,最好把它们写到另外一个文件,比如叫 .mutt.alias. 然后在 .muttrc 里加上:
|
||||
|
||||
source ~/.mutt.alias
|
||||
|
||||
在里面写诸如
|
||||
|
||||
alias music Music <music@ustc.edu.cn>
|
||||
alias video 科大影视 <video@ustc.edu.cn>
|
||||
.........
|
||||
|
||||
你还可以设置一个变量:
|
||||
|
||||
set alias_file=~/.mutt.alias
|
||||
|
||||
这样你在 index 里按 "a",就可以把来信人加入到这个 alias 文件了。
|
||||
mutt附件格式问题
|
||||
|
||||
mutt(和gnus一样)默认的附件格式是rfc2231,但实际上大多数邮件客户端却是rfc2047。据说rfc2231才是标准的。为了迎合其他人,需要改变mutt的附件格式,要打补丁,详见 brep的主页,可以使用brep打的包。
|
||||
|
||||
然后在.muttrc中增加
|
||||
|
||||
set rfc2047 parameter=yes
|
||||
|
||||
mutt处理 HTML 附件
|
||||
|
||||
mutt 可以处理任何类型的附件。因为它可以调用合适的程序来处理它们。为了直接在 mutt 的窗口里显示 HTML,先aptitude安装lynx, 你需要在 ~/.mailcap 文件加入:
|
||||
|
||||
text/html; lynx --dump %s; nametemplate=%s.html; copiousoutput
|
||||
|
||||
在 ~/.muttrc 加入:
|
||||
|
||||
auto_view text/html
|
||||
|
||||
mutt处理doc附件问题
|
||||
|
||||
许多人喜欢发送微软的doc文档作为附件,使用wvware可以转化成为html文档或者 latex文档。mutt窗口可以显示html,先aptitude安装wv,然后在~/.mailcap中加入
|
||||
|
||||
application/msword; wvHtml --charset=gb2312 %s - | lynx --dump -stdin; nametemplate=%s.html; copiousoutput
|
||||
|
||||
在~/.muttrc中加入
|
||||
|
||||
auto_view text/html application/msword
|
||||
|
||||
OK,mutt已经配置好了,运行试试吧,
|
||||
|
||||
$ mutt
|
||||
|
||||
下面是说明配置exim4的配置和postfix的配置(MuttConfig:postfix), 还有fetcmail的使用(MuttConfig:fetchmailrc)。喜欢它们的人可以看。
|
||||
配置exim4
|
||||
|
||||
$ su
|
||||
# dpkg-reconfigure exim4-config
|
||||
|
||||
根据你的信箱的情况,如果你的信箱是要求smtp认证的,(不需要smtp认证的跳过MuttConfig:nosmtp1)
|
||||
|
||||
按照如下的流程,比如科大信箱mail.ustc.edu.cn现在就是要smtp认证的,那么就要按照下面所示.
|
||||
|
||||
(1)将配置文档拆分成小文件么? 否
|
||||
(2)选择“用smarthost发信;通过smtp或fetchmail接受邮件”
|
||||
(3)系统邮件名称,随意;(可以写xxx@mail.ustc.edu.cn)
|
||||
(4)要监听的入站 SMTP 连接的 IP 地址:127.0.0.1 (这样,就只有本机可以利用exim4)
|
||||
(5)其它可接受的邮件目的地址:(empty)
|
||||
(6)为这些主机进行邮件转发:(empty)
|
||||
(7)负责处理从本机寄出的邮件的机器(smarthost): 202.38.64.8
|
||||
(8)要在寄出的邮件中隐藏本地邮件名称吗? 是
|
||||
(9)本地用户的可视域名:同3)
|
||||
(10)保持最小 DNS 查询量吗(按需拔号 Dial-on-Demand)? 否
|
||||
|
||||
还要修改几个配置文件:
|
||||
|
||||
(1) /etc/exim4/passwd.client,smtp的帐号密码设置,加入:
|
||||
|
||||
202.38.64.8:用户名:密码
|
||||
|
||||
对于学生要用 用户名@mail.ustc.edu.cn
|
||||
|
||||
(2) /etc/exim4/exim4.conf.template,exim4配置文件,找到下面的文字
|
||||
|
||||
# Because AUTH PLAIN and AUTH LOGIN send the password in clear, we
|
||||
# only allow these mechanisms over encrypted connections by default.
|
||||
# You can set AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS to allow unencrypted
|
||||
# clear text password authentication on all connections.
|
||||
|
||||
看懂了就知道了,因为email服务器的授权方式是明文方式验证的,所以要加入:
|
||||
|
||||
AUTH_CLIENT_ALLOW_NOTLS_PASSWORDS = 1
|
||||
|
||||
对于没有smtp认证的邮箱,在dpkg-reconfigure exim4-config的第二步时候选择
|
||||
|
||||
互联网站;直接通过 SMTP 发送或接收信件
|
||||
|
||||
其他的基本上默认或者参考上面的列表就可以了,也不需要配置上面的两个文件。
|
||||
|
||||
配置之后重新启动exim4
|
||||
|
||||
# /etc/init.d/exim4 restart
|
||||
|
||||
配置postfix
|
||||
|
||||
根据你的信箱的情况,如果你的信箱是要求smtp认证的,(不需要smtp认证的跳过MuttConfig:nosmtp2)
|
||||
|
||||
$ sudo dpkg-reconfigure postfix
|
||||
|
||||
按照提示一步一步做,修改配置类型为internet with smarthost
|
||||
|
||||
relayhost 设置为202.38.64.8
|
||||
|
||||
配置修改几个文件
|
||||
|
||||
1./etc/postfix/master.cf 修改
|
||||
|
||||
smtp inet n - - - - smptd
|
||||
|
||||
为
|
||||
|
||||
smtp inet n - n - - smtpd -v
|
||||
#可以在/var/log/message中找到错误信息
|
||||
|
||||
2, /etc/postfix/main.cf中增加
|
||||
|
||||
smtpd_sasl_auth_enable = yes
|
||||
# 允许明文
|
||||
smtpd_delay_reject=yes
|
||||
smtpd_recipient_restrictions = permit_mynetworks permit_sasl_authenticated
|
||||
permit_auth_destination reject
|
||||
smtpd_client_restrictions = permit_sasl_authenticated
|
||||
broken_sasl_auth_clients =yes
|
||||
smtpd_sasl_security_options = noanonymous
|
||||
smtp_sasl_password_maps = hash:/etc/postfix/saslpass
|
||||
# smtp认证的密码文件
|
||||
|
||||
3,编辑/etc/postfix/saslpass
|
||||
|
||||
202.38.64.8 user:password
|
||||
# user应该是xxx@mail.ustc.edu.cn
|
||||
|
||||
为了加速,用postmap生成数据库:
|
||||
|
||||
postmap hash:/etc/postfix/saslpass
|
||||
|
||||
为了安全
|
||||
|
||||
chown -v root:root /etc/postfix/saslpass*
|
||||
chmod -v 600 /etc/postfix/saslpass*
|
||||
|
||||
若是不认证的,也是选择
|
||||
|
||||
互联网站;直接通过 SMTP 发送或接收信件
|
||||
|
||||
配置fetchmail
|
||||
|
||||
新建~/.fetchmailrc
|
||||
|
||||
在里面写类似
|
||||
|
||||
defaults
|
||||
mda "/usr/bin/procmail -d user"
|
||||
set daemon 60
|
||||
poll 202.38.64.8
|
||||
uidl
|
||||
protocol POP3
|
||||
user "xxx@mail.ustc.edu.cn"
|
||||
password "xxxxxx"
|
||||
keep
|
||||
poll bbs.ustc.edu.cn
|
||||
....
|
||||
....
|
||||
|
||||
上面user 表示你自己的用户名,
|
||||
|
||||
uidl表示只收取新的信件,
|
||||
|
||||
keep表示不删服务器上的邮件。
|
||||
|
||||
注意~/.fetchmailrc 的属性设为 600 若太高比如超过710, fetchmail 不予启动(处于安全的考虑)。
|
||||
参考文献
|
||||
|
||||
1,王垠主页的mutt配置的说明,
|
||||
|
||||
2,jamescsy, [指南]Exim4+fetchmail+mutt在debian下收发电子邮件
|
||||
|
||||
3,lo0ol, postfix+mutt+tsocks配置成功.可以通过代理认证smtp server发信
|
||||
|
||||
4,冷风, 带smtp认证的postfix配置
|
||||
|
||||
5,yixiu, 使用msmpt+mutt+getmail4+procmail处理ustcmail
|
||||
26
Zim/Utils/SSH_and_SSL.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-10-12T18:18:16+08:00
|
||||
|
||||
====== SSH and SSL ======
|
||||
Created Wednesday 12 October 2011
|
||||
|
||||
ssl是通讯链路的附加层。可以包含很多协议。https, ftps, .....
|
||||
ssh只是加密的shell,最初是用来替代telnet的。通过port forward,也可以让其他协议通过ssh的隧道而起到加密的效果。
|
||||
|
||||
SSL是一种国际标准的加密及身份认证通信协议,您用的浏览器就支持此协议。SSL(Secure Sockets Layer)最初是由美国Netscape公司研究出来的,后来成为了Internet网上安全通讯与交易的标准。SSL协议使用通讯双方的客户证书以及CA根证书,允许客户/服务器应用以一种不能被偷听的方式通讯,在通讯双方间建立起了一条安全的、可信任的通讯通道。它具备以下基本特征:信息保密性、信息完整性、相互鉴定。 主要用于提高应用程序之间数据的安全系数。SSL协议的整个概念可以被总结为:一个保证任何安装了安全套接字的客户和服务器间事务安全的协议,它涉及所有TC/IP应用程序。
|
||||
|
||||
|
||||
SSH的英文全称是Secure SHell。通过使用SSH,你可以把所有传输的数据进行加密,这样“中间人”这种攻击方式就不可能实现了,而且也能够防止DNS和IP欺骗。还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
|
||||
|
||||
SSH有很多功能,它既可以代替telnet,又可以为ftp、pop、甚至ppp提供一个安全的“通道”。
|
||||
|
||||
SSH是由客户端和服务端的软件组成的,有两个不兼容的版本分别是:1.x和2.x。
|
||||
用SSH 2.x的客户程序是不能连接到SSH 1.x的服务程序上去的。OpenSSH 2.x同时支持SSH 1.x和2.x。
|
||||
|
||||
SSH的安全验证是如何工作的从客户端来看,SSH提供两种级别的安全验证。
|
||||
第一种级别(基于口令的安全验证)只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“__中间人__”这种方式的攻击。
|
||||
|
||||
第二种级别(基于密匙的安全验证)需要依靠密匙,也就是你必须为自己创建一对密匙,并把__公用密匙__放在需要访问的服务器上。如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后,先在你在该服务器的家目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致,服务器就用公用密匙加密“__质询__”(challenge)并把它发送给客户端软件。客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器。用这种方式,你必须知道自己密匙的口令。但是,与第一种级别相比,第二种级别不需要在网络上传送口令。第二种级别不仅加密所有传送的数据,而且“中间人”这种攻击方式也是不可能的(因为他没有你的私人密匙)。但是整个登录的过程可能需要10秒。
|
||||
|
||||
sftp有特殊的通讯端口和命令集(尽管和ftp命令类似),是和ssh平行的协议。建立连接的部分和ssh类似。一般情况下,带有ssh服务器端,也带有sftp服务(当然,你也可以不开)。ftp over ssh就是建立连接时使用ssh协议,然后,利用ssh的转发,使用ftp的命令集来传输文件。也就是说,是建立在ssh协议上的ftp.
|
||||
221
Zim/Utils/SSH_and_SSL/SSH_and_SSH详解.txt
Normal file
@@ -0,0 +1,221 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-10-12T18:26:50+08:00
|
||||
|
||||
====== SSH and SSH详解 ======
|
||||
Created Wednesday 12 October 2011
|
||||
http://www.ws-ping.com/support/ws_ftp/guide/wsftpug76/08sslutil.html
|
||||
Chapter 8: Security
|
||||
|
||||
This chapter describes the two security protocols found in WS_FTP Pro: SSL and SSH. It also explains how to configure WS_FTP Pro to use these protocols to make secure connections.
|
||||
|
||||
===== SSL =====
|
||||
|
||||
SSL (Secure Socket Layer) is a protocol for encrypting and decrypting data sent across direct internet connections. When a client makes an SSL connection with a server, all data sent to and from that server is encoded with a complex mathematical algorithm that makes it extremely difficult to decode anything that is intercepted.
|
||||
|
||||
The following is a step by step illustration of how SSL works.
|
||||
|
||||
**Step 1. **The client makes the initial connection with the server and requests that an SSL connection be made.
|
||||
客户端发起SSL连接请求。
|
||||
|
||||
**Step 2.** If the server is properly configured, the server will send to the client its certificate and public key.
|
||||
服务器支持SSL的话就返回自己的证书(证书里包含有自己的公钥)。
|
||||
|
||||
**Step 3. **The client compares the certificate from the server to a **trusted authorities database**. If the certificate is listed there, it means the client trusts the server and will move to step 4. If the certificate is not listed there, the user must **add the certificate** to the trusted authorities database before going to step 4.
|
||||
客户端会对服务器发过来的证书进行比较验证(一般是将签名该证书的根证书与本地信任的根证书列表进行查找比较),若失败,则客户端必须将该证书添加到本地数据库后才能继续与服务器建立连接。
|
||||
|
||||
**Step 4. **The client uses that public key to encrypt a session key and sends the session key to the server. If the server asks for the client's certificate in Step 2, the client must send it at this point.
|
||||
客户端用收到证书里的公钥加密一个标识这次连接会话的key然后将其发送给服务器。如果服务器要求验证客户端的证书,这时客户端也必须同时将自己的证书发给服务器。
|
||||
|
||||
**Step 5. **If the server is **set up** to receive certificates, it compares the certificate it received with those listed in its trusted authorities database and either accepts or rejects the connection.
|
||||
服务器同样对客户端发过来的证书进行比较验证。
|
||||
|
||||
If the connection is rejected, a **fail message** is sent to the client. If the connection is accepted, or if the server is not set up to receive certificates, it decodes the session key from the client with its own private key and sends a success message back to the client, thereby opening a secure data channel.
|
||||
如果服务器接受连接,会用自己的私钥对客户端发过来的session key进行解密,如果成功则发送一条消息给客户端,安全通道正式建立。
|
||||
|
||||
===== PS: =====
|
||||
**SSL一般用于client-server环境,而且对服务器的认证是必须的,但是对客户端的认证是可选的,这是因为一般是对客户端发往服务器的信息(如帐号、密码等)进行加密。**
|
||||
|
||||
The key to understanding how SSL works is in understanding the parts that make SSL itself work. The following is a list of these parts and the role each plays.
|
||||
|
||||
**Client.** In this case, the client is WS_FTP Pro.
|
||||
|
||||
**Certificate.** The Certificate file **holds** the identification information of the client or server. This file is used during **connection negotiations** to identify the parties involved. In some cases, the client's certificate must **be signed** by the server's certificate in order to open an SSL connection. Certificate files have the__ .crt__ ending.
|
||||
|
||||
**Session Key. **The session key is what both the client and the server use to encrypt data. It is created by the** client**.
|
||||
客户端创建该key然后用服务器的公钥对其加密后发给服务器,服务器用自己的私钥对其解密。成功后用客户端的公钥(若有的话)对其加密,然后发给客户端,客户端用自己的私钥对其解密验证。
|
||||
|
||||
**Public Key. **The public key is the **device **with which the client encrypts a session key. __It does not exist as a file, but is a by-product of the creation of a certificate and private key. __Data encrypted with a public key can only be decrypted by the private key that made it.
|
||||
|
||||
**Private Key.** The private key decrypts the client's session key that is encrypted by a public key. The private key file has the __.key __ending. Private keys should NEVER be distributed to anyone.
|
||||
|
||||
**Certificate Signing Request.** A certificate signing request is generated each time a certificate is created. This file is used when you need to have your certificate signed. Once the Certificate Signing Request file is signed, a new certificate is made and can be used to replace the unsigned certificate.
|
||||
证书签名请求文件是和证书文件一起生成的,而且是配对使用的。该文件一旦被签名,就会重新生成一个新的已签名证书。
|
||||
|
||||
===== How to make an SSL connection =====
|
||||
|
||||
To make an SSL connection with a server** configured for SSL**.
|
||||
|
||||
* Be sure to select the Secure (SSL) option when you follow the directions for configuring a site.
|
||||
* After you click Connect, WS_FTP Pro tells the server that you want to make an SSL connection. The server then transmits to you an **identifying certificate**, letting the client know **who the server is.** If that certificate is already listed in your __Trusted Authority database__, the connection is made.
|
||||
* If that certificate is not listed as a trusted authority, the Non-Trusted Authority dialog box appears.
|
||||
对于服务器发送的证书,客户端不信任的话,必须手动将其添加到本地数据库中。
|
||||
* Select the option you need and click OK. If the server does not require a certificate to be returned, the secure connection will be established. All data transmitted between you and the server will be encrypted.
|
||||
|
||||
If the server you are attempting to make a connection to asks WS_FTP Pro to send back a certificate, follow the direction for Client Certificate Verification.
|
||||
|
||||
===== Client Certificate Verification 服务器对客户端证书认证 =====
|
||||
|
||||
If the server you are attempting to make a connection to __requires__ your client to send an identifying certificate back to the server, you must:
|
||||
|
||||
* Configure the site with the Secure (SSL) option selected.
|
||||
* Create a certificate. Refer to the section "Generating a Certificate" for more information.
|
||||
手动生成一个证书。
|
||||
* Send the **Certificate Signing Request file **to your server administrator.
|
||||
将和该证书同时生成的证书签名请求文件发送给系统管理员,请求其签名。
|
||||
* Once the server administrator **signs **the Certificate Signing Request, it will be sent back to you.
|
||||
管理员对该文件签名后会生成一个新的证书(以前的可以不使用)会发送给客户端
|
||||
* When you receive the file, follow the directions for "Selecting a Certificate", selecting the new certificate to go in the Certificate box.
|
||||
客户端可以使用该证书连接服务器
|
||||
* Connect to the server.
|
||||
|
||||
===== Generating a Certificate =====
|
||||
|
||||
To create an SSL certificate:
|
||||
|
||||
From the Options menu, select Configure SSL. The **SSL Utilities** window appears.
|
||||
Click the Certificate Creation tab.
|
||||
|
||||
Enter a name in the **Certificate Set Name box**. This will be the name of the certificate that is generated by WS_FTP Pro.
|
||||
Click the Browse (...) button in the **Output Location box** to select the folder you want the certificate created in.
|
||||
Enter information in all of the **Certificate Information boxes**:
|
||||
|
||||
|
||||
|
||||
// City/Town.// City or town where you are located. (Ex. Augusta)
|
||||
|
||||
// State/Province. //State or Province where you are located. (Ex. Georgia)
|
||||
|
||||
// Organization.// Company or individual user name.
|
||||
|
||||
// Common Name.// This can be either the **name of the person** creating the certificate or the** fully qualified domain name **of the server associated with the host.
|
||||
|
||||
__Pass Phrase. __Pass phrase that is to be used to **encrypt the private key**. It is important to remember this pass phrase. The pass phrase can be any combination of words, symbols, spaces, or numbers.
|
||||
|
||||
// Pass Phrase Confirmation.// Re-enter the same pass phrase as above.
|
||||
|
||||
// Country. //The country you are in. This must be a valid two letter country code. (Ex. US)
|
||||
|
||||
// E-mail.// E-mail address of the person the certificate belongs to.
|
||||
|
||||
// Unit. //Name of organizational unit. (Ex. Research and Development)
|
||||
|
||||
After all of the boxes are filled in correctly, click Create to generate the __keys, certificate, and certificate signing request.__ If all of the boxes are not filled in, you cannot create the certificate.
|
||||
|
||||
If you are creating a certificate to be used by WS_FTP Pro, you should send the **certificate signing request **(by E-mail) to your server administrator. If they require it, they will sign the certificate and return it to you. The returned certificate should be the one you identify in the Certificate Selection tab.
|
||||
|
||||
===== Selecting a Certificate =====
|
||||
|
||||
The Certificate Selection tab is used to choose__ which private key and certificate __you want to use during __SSL connection negotiations__. If a new certificate has not been created, follow the directions for "Generating a Certificate".
|
||||
|
||||
To select an SSL Certificate:
|
||||
|
||||
Click the Browse (...) button next to the** Private Key box** to select the private key you want to use during SSL negotiation.
|
||||
Click the Browse (...) button next to the** Certificate box **to select the certificate you want to use during SSL negotiation. The certificate you use must have been created using the key you selected for the Private Key box.
|
||||
|
||||
注意:私钥和证书必须要配对使用。
|
||||
Enter the __pass phrase associated with that certificate__ in both the Pass Phrase and the Pass Phrase Confirmation boxes. A pass phrase can be any combination of words, symbols, spaces or numbers. It is case sensitive and must be written exactly the same way each time it is used.
|
||||
|
||||
Without the correct pass phrase in both boxes, the certificate and private key cannot be verified and the selection cannot be saved.
|
||||
Click Apply to save your entries.
|
||||
|
||||
Clicking the Reset button erases what you have done since the last time new settings were applied.
|
||||
|
||||
====== Trusted Authorities ======
|
||||
|
||||
The Trusted Authorities tab stores **a list of certificate names** that are recognized by WS_FTP Pro.
|
||||
|
||||
Certificate Display:
|
||||
|
||||
**Issued To.** Who the certificate was issued to.
|
||||
|
||||
**Issued By.** Who the certificate was__ signed__ by.
|
||||
|
||||
**Expires**. Date on which the certificate expires.
|
||||
|
||||
==== Adding a Certificate(添加本地信任的证书,一般为根证书) ====
|
||||
|
||||
To add a certificate to the database:
|
||||
|
||||
Click the Import button and select the path and file name for the certificate. The **Add Certificate? dialog box** appears.
|
||||
|
||||
Review the information on that dialog box and click Yes to add the certificate to the database.
|
||||
|
||||
===== Exporting a Certificate =====
|
||||
|
||||
To export a certificate from the** Trusted Authorities database**:
|
||||
|
||||
Select the certificate you want to copy out of your database.
|
||||
Click the Export button.
|
||||
|
||||
Select the folder you want to copy the certificate to and enter the name you want to save the certificate file as.
|
||||
Click OK.
|
||||
|
||||
===== Removing a Certificate =====
|
||||
|
||||
To remove a certificate:
|
||||
|
||||
Select the certificate to be removed.
|
||||
Click Remove.
|
||||
A warning appears advising you to export the certificate before you remove it. Removing the certificate deletes the certificate file.
|
||||
Click OK to remove the certificate.
|
||||
|
||||
====== Non-Trusted Certificate ======
|
||||
|
||||
When you connect to a server using the SSL connection option, that server sends you a certificate. __If that certificate is not listed on the Trusted Authority tab, or if it was not signed by a certificate on this list__, this dialog box appears.
|
||||
|
||||
Certificate Information:
|
||||
|
||||
**Issued To. **Name of the person or company who the certificate belongs to.
|
||||
|
||||
**Issued By. **Name of the person or company who signed the certificate.
|
||||
|
||||
**Active From. **The date on which this certificate was activated.
|
||||
|
||||
**Expires On. **The date the displayed certificate will no longer be a valid certificate.
|
||||
|
||||
Options
|
||||
|
||||
Allow this connection only. If this option is selected, the connection will be made, but WS_FTP Pro will still not recognize the certificate as a trusted authority. The next time you attempt to connect to this server, this dialog box appears once again.
|
||||
|
||||
**Trust this certificate.** If this option is selected, the connection will be made and the certificate will be added to the trusted authority database in the Trusted Authority tab, so future connections can be made without you being prompted.
|
||||
|
||||
Do not allow this connection. If this option is selected, the connection will be terminated.
|
||||
|
||||
====== SSH ======
|
||||
|
||||
SSH (Secure Shell) is a security protocol that allows you to make a secure connection to a server that has the **SSH and SFTP** (Secure File Transfer Protocol) protocols installed. Where FTP servers usually `listen' on port 21 for connection, SSH servers use port **22**.
|
||||
|
||||
__Where SSL attempts to make a connection with unencrypted channels, SSH encrypts all communications to and from the client and server.__
|
||||
|
||||
When an SSH connection is made, SFTP is the protocol that is used to perform all tasks on that single secure connection.
|
||||
|
||||
===== How to make an SSH connection =====
|
||||
|
||||
Making an SSH connection requires little additional configuration to new or your existing site profiles.
|
||||
|
||||
When creating a new site profile through the New Site Wizard, simply change the Server Type to SFTP/SSH when prompted by the wizard.
|
||||
|
||||
If editing an existing site profile:
|
||||
|
||||
Select the site from the configured sites list.
|
||||
Click the Edit button.
|
||||
Click the Advanced tab.
|
||||
In the Server type pull-down, select SFTP/SSH.
|
||||
Click OK.
|
||||
|
||||
When you use that profile to make a connection, the client will automatically attempt to make an SSH connection on port 22 of that server.
|
||||
|
||||
===== SSL vs. SSH =====
|
||||
|
||||
With both SSL and SSH, it is up to the administrator of the server you are trying to make a connection with to tell you which server type is being run at that address. If you do not know, and attempt to make an SSL connection or an insecure connection to an SSH server, the connection will fail, even if you change the port to 22 in the Site Profile.
|
||||
90
Zim/Utils/SSH_and_SSL/SSH_tunnel_tips.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-06T18:29:40+08:00
|
||||
|
||||
====== SSH tunnel tips ======
|
||||
by pluskid, on 2009-08-14, in Tool 11 comments
|
||||
http://blog.pluskid.org/?p=369
|
||||
|
||||
以前接触 SSH 的时候我就在文档上见过 SSH tunnel 相关的东西,然而当时没有怎么看明白,也就一直没有深究,直到最近需求越来越多了,才终于发现这个东西原来这么有用,于是记录在此。
|
||||
|
||||
**SSH tunnel** 主要有三种,一种是** dynamic application-level port forwarding **,可以用来作为 SOCKS proxy ,通常翻墙就是用的这种端口映射;一种是** Local Forwarding** ,主要用于提供常规的加密隧道,例如让 IMAP 协议通过这个加密隧道,避免密码在网络上被人监听到;一种是 **Remote Forwarding** ,可以用于逆向穿透 NAT 。其实,另外还有一种专门为 X 打造的 **X11 Forwarding** ,一般不会用到,Linux 下远程登录通常不会需要开启 X 程序,或者有其他更好用的方法,因此我们这里并不打算介绍这个。
|
||||
|
||||
首先我们来假定一个网络环境:有一个防火墙,在防火墙内部有一个机器 H ,通过 NAT 访问 Internet ,并且在防火墙外的 Internet 上的机器 T 上**有一个 ssh 帐号**,而另一台 Internet 上的机器 S 则是一台公共服务器,例如 Google 的服务器。如下图所示:
|
||||
{{./ssh.png}}
|
||||
ssh
|
||||
首先来说 Local Forwarding ,相关的文档上都用的是阅读邮件这个经典的例子:用户在 T 上有一个 IMAP 服务器,本来他可以直接连接到 T:143 上阅读邮件的,但是这是未加密连接,如果你的 IMAP 服务器是用明文密码验证的方式的话,就很糟糕了,这样你的密码很容易被别人窃听到。这个时候 SSH 隧道就出来了,通过如下命令可以建立一个 SSH 隧道:
|
||||
|
||||
__ssh -L 9143:localhost:143 T__
|
||||
|
||||
#这里的local意思是,本地的ssh客服端程序把由本地127.0.0.1:9143端口发出的数据通过与T间的ssh加密隧道转发到远程的143端口,由于指定了localhost,故是T上的143端口。
|
||||
|
||||
首先不看参数,这个命令是发起一个 ssh 连接到主机 T ,然后选项 -L 表示 Local Forwarding ,**9143 表示本地(亦即 H)的端口,然后 localhost:143 则是远程所对应的主机和端口**。这样一来,你在 H 上连接端口 9143 ,就相当于你在 T 上连接 localhost:143 一样,SSH 建立的隧道会帮你在两个主机间传递信息。现在只要配置 H 上的邮件客户端去连接 localhost:9143 ,就能通过加密的方式访问到 T 上的 localhost:143 这个邮件服务器了。注意两个主机上的 localhost 的区别。
|
||||
|
||||
当然隧道并不限于 localhost(即远程的运行着sshd的服务器T) ,如果你愿意,可以做这样一个映射:
|
||||
|
||||
__ssh -L 9999:www.google.com:80 T__
|
||||
#由于指定了www.google.com:,本地的ssh客户端进程会把发往本地127.0.0.1:9999端口的数据通过加密隧道传给T,然后T的sshd服务进程会把这个请求转发到www.google.com:80(sshd会根据传给他的**应用层协议类型**也就是目的端口号和IP或主机名来判断),并将返回的数据通过隧道传到H的127.0.0.1:9999端口。
|
||||
|
||||
这样,你可以在 H 的浏览器里输入 localhost:9999 访问到 Google 了。注意到 H 和 T 之间的数据传输是加密的,所以,如果 H 是处在伟大的局域网内,而 T 是在外部的话,可以通过这样的方法来访问 Google 而不受防火墙的限制。不过这种方法**每个本地端口只能映射到一个远程主机的固定端口**,很不方便。
|
||||
|
||||
|
||||
要用作代理通常还是使用 __dynamic application-level port forwarding__ 的方式,如下:
|
||||
|
||||
__ssh -D 9999 T__
|
||||
|
||||
#这时本地的ssh客户端进程担任了一个socks服务器的角色,他监听本地的127.0.0.1:9999端口,把从该端口发出的数据通过隧道传到T的sshd进程,然后sshd再根据请求数据中的信息(IP地址或主机名加端口号)发送相应的请求然后把返回的数据通过隧道传给客户端的127.0.0.1:9999
|
||||
|
||||
这样建立起来的隧道实际上是一个 __SOCKS 代理__,当然要使用 **SOCKS 代理需要客户端能够支持才行**,比如在 Firefox 中,只要在代理处填写 localhost:9999 并勾选 SOCKS5 代理即可。另外,还可以使用诸如 ProxyChains 之类的程序让本身不支持 SOCKS 代理的程序能够“透明地”使用 SOCKS 代理,不过我并没有尝试过,不知道稳定性如何。
|
||||
|
||||
最后要介绍的就是 Remote Forwarding 了,也就是ssh客户端帮助远程主机转发,首先看命令吧:
|
||||
|
||||
__ssh -R 9923:10.13.21.88:23 T__
|
||||
|
||||
-R的意义是:在远程主机T上指定一个sshd监听的端口号如9923然后他向该端口发的数据会通过隧道被H的ssh客户端接收,然后ssh客户端会将请求数据转发给本地(不一定是本机)的主机和端口号。
|
||||
|
||||
这里 10.13.21.88 是 H 所在的局域网里的一台主机,23 是 telnet 默认的端口,其实这就是浙大飘渺水云间 bbs (亦即“88”)的校内地址了,由于是在局域网内,Internet 上的 T 是访问不到它的,现在 H 建立了一个到 T 的 Remote Forwarding ,对应之前的 Local Forwarding 的意思,应该能猜到了吧?现在在 T 上可以通过访问 localhost:9923 来上 88 了。 :D 换句话说,在 T 上访问 localhost:9923 相当于在 H 上访问 10.13.21.88:23 ,这成了一个反向的隧道。
|
||||
|
||||
综上,Local 和Remote都是相对与本地H的__ssh客户端__进程来说的,前者是将发往本地指定端口上的数据通过隧道发往sshd服务器,sshd再做处理。后者是本地的ssh客户进程将远程sshd传过来的数据(sshd监听并转发特定端口)转发到相应的主机。
|
||||
|
||||
另外,上面三种 Forwarding 默认建立的 socket 都是监听本机的 **loopback** 地址的,这样外面的机器是不能访问这个端口映射的。对于最后那个飘渺水云间的隧道来讲,默认情况下,T 虽然可以通过 localhost:9923 来上 88 ,但是 S 却不能通过 T:9923 来访问到,而是会得到一个 Connection Refused 的错误,这样做也是为了安全起见,不过,如果确实想要让__这个隧道可以从其他主机访问到的话__,上面三个命令都可以在映射参数前面再加一个地址参数。例如飘渺水云间的那个映射其实等价于:
|
||||
|
||||
ssh -R localhost:9923:10.13.21.88:23 T
|
||||
|
||||
把 localhost 改成 * 就可以让其他机器也访问到了(注意加上引号以防止 shell 把星号给展开了):
|
||||
|
||||
__ssh -R '*:9923:10.13.21.88:23' T__
|
||||
|
||||
唔,还有一点要说明的是,对于 -L 和 -D 来说,都是这样就可以了,而 -R 则还需要远程的 sshd 配置一下__ GatewayPorts __选项,默认情况下是 no ,这样会无视掉客户端的请求,强制 bind 到 loopback 地址上,而 yes 则相当于强制 * ,如果设置成 clientspecified 则允许客户端来选择(注意,-R选项时的远程sshd监听的端口号是由ssh客户端在命令行上指定的)。因此在 /etc/ssh/sshd_config 文件里添加这样一行:
|
||||
|
||||
__GatewayPorts clientspecified__
|
||||
|
||||
再重启 ssh 服务即可。虽然学校提供了 RVPN 可以从校外访问到校内的资源,但是并没有提供 Linux 下的解决方案。在没有校外独立 IP 的情况下用这样的方法在外面访问学校的资源就变得非常有用了。要是 -D 也能有一个对应的 Reverse 的方案也许会更方便一些,不过也许可以用 -R 和 -D 桥接一个:
|
||||
|
||||
H$ ssh -D 9999 localhost
|
||||
H$ ssh -R 9999:localhost:9999 T
|
||||
|
||||
在 T 上使用 localhost:9999 作为 SOCKS 代理,而该端口的数据会被 forward 到 H 上的 localhost:9999 ,那里是实际的 SOCKS 代理服务器。不过我没有实际测试过是不是真的可以用。 :p
|
||||
|
||||
最后再说一句,**FTP 是另一个经典的明文传输密码的协议,但是它却没法通过 SSH 隧道使用,因为它需要另外打开一个 socket 来传输数据**,这时就不在 SSH 的接管范围之内了,我想这也许是 SFTP 这个东西诞生的直接原因吧。其实使用了 -R 的端口映射之后,要 scp 回来是一件很容易的事,例如:
|
||||
|
||||
H$ ssh -R 9922:localhost:22 T
|
||||
T$ scp foo.txt -P 9922 localhost:~/
|
||||
|
||||
可以将 T 上的 foo.txt 拷贝回 H 的主目录中。当然,如果只是为了做一个端口映射,可不必打开一个远程 shell ,只要再为 ssh 加上 -Nf 参数即可,具体是什么意思自己 man 吧。它会在后台运行,一直等待到对应隧道端口的连接。需要注意的是,在有了第一个连接之后,如果连接数降为零了,它会自动退出。所以我通常还是会打开远程 shell ,不过使用 screen 把它放在后台去,就不会妨碍了,需要的时候可以调出来,也可以方便地控制它什么时候退出。 :)
|
||||
|
||||
最后,在客户端的 ~/.ssh/config 里加入
|
||||
|
||||
ServerAliveInterval 180
|
||||
|
||||
这样可以防止长时间的 idle 导致 ssh 连接被自动断开。
|
||||
|
||||
不知道 iptables ,做端口转发?SSH 主要是做隧道了,要两台机器参与,端口转发的话是同一台机器双 IP 的情况吧?
|
||||
|
||||
关于用reversed tunneling做rvpn
|
||||
往往情况是T也不是公网ip 例如在firewall后面
|
||||
那H就不能ssh T了
|
||||
|
||||
结果是需要一个middleman,H,T都能访问到 那可以连上
|
||||
可是谁能提供一个。。。
|
||||
|
||||
BIN
Zim/Utils/SSH_and_SSL/SSH_tunnel_tips/ssh.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
44
Zim/Utils/SSH_and_SSL/SSH和SSL比较.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-10-12T19:31:46+08:00
|
||||
|
||||
====== SSH和SSL比较 ======
|
||||
Created Wednesday 12 October 2011
|
||||
|
||||
====== 一、SSH介绍 什么是SSH? ======
|
||||
|
||||
传统的网络服务程序,如:ftp、pop和telnet在本质上都是不安全的,因为它们在网络上用明文传送口令和数据, 别有用心的人非常容易就可以截 获这些口令和数据。而且,这些服务程序的安全验证方式也是有其弱点的, 就是很容易受到“中间人”(man-in-the-middle)这种方式的攻 击。所谓“中间人”的攻击方式, 就是“中间人”冒充真正的服务器接收你的传给服务器的数据,然后再冒充你把数据传给真正的服务器。 服务器和你之间的数 据传送被“中间人”一转手做了手脚之后,就会出现很严重的问题。
|
||||
|
||||
SSH的英文全称是Secure Shell。通过使用SSH,你可以把所有传输的数据进行加密,这样“中间人”这种攻击方式就不可能实现了, 而且也能够防止DNS和IP欺骗。还有一个 额外的好处就是传输的数据是__经过压缩__的,所以可以加快传输的速度。 SSH有很多功能,它既可以代替telnet,又可以为ftp、pop、甚至ppp提 供一个安全的“通道”。
|
||||
|
||||
最初SSH是由芬兰的一家公司开发的。但是因为受版权和加密算法的限制,现在很多人都转而使用__OpenSSH__。 OpenSSH是SSH的替代软件,而且是免费的,可以预计将来会有越 来越多的人使用它而不是SSH。
|
||||
|
||||
SSH是由客户端和服务端的软件组成的,有两个**不兼容的版本分别是:1.x和2.x**。 用SSH 2.x的客户程序是不能连接到SSH 1.x的服务程序上去的。OpenSSH 2.x同时支持SSH 1.x和2.x。
|
||||
|
||||
===== SSH的安全验证是如何工作的 =====
|
||||
|
||||
从客户端来看,SSH提供两种级别的安全验证。
|
||||
|
||||
第一种级别(基于__口令__的安全验证)只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密, 但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器, 也就是受到“中间人”这种方式的攻击。
|
||||
|
||||
第二种级别(基于__密匙__的安全验证)需要依靠密匙,也就是你必须为自己创建一对密匙,并把__公用密匙放在需要访问的服务器__上。 如果你要连接到SSH服务器 上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后, 先在你在该服务器的**家目录下寻找你的公用密匙**,然后把它和你__发送过来的公用密匙__进行比较。如果两个密匙一致, 服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。 客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器。
|
||||
|
||||
用这种方式,你必须知道自己密匙的口令。但是,与第一种级别相比,第二种级别不需要在网络上传送口令。
|
||||
|
||||
第二种级别不仅加密所有传送的数据,而且“中间人”这种攻击方式也是不可能的(因为他没有你的私人密匙)。 但是整个登录的过程可能需要10秒。
|
||||
|
||||
====== 二、SSL介绍(Secure socket Layer & Security Socket Layer) ======
|
||||
|
||||
一个应用程序的安全需求在很大程度上依赖于将如何使用该应用程序和该应用程序将要保护什么。不过,用现有技术实现强大的、 一般用途的安全通常是可能的。认证就是一个很好的示例。
|
||||
|
||||
当顾客想从 Web 站点购买某个产品时,顾客和 Web 站点__都要__进行认证。顾客通常是以提供__名字和密码__的方式来认证他自己。 另一方面,Web 站 点通过交换一块签名数据和一个有效的__ X.509 证书__(作为 SSL 握手的一部分)来认证它自己。 顾客的浏览器验证该证书并用所附的公用密钥验证签 名数据。一旦双方都认证了,则交易就可以开始了。
|
||||
|
||||
安全套接字层(Secure Sockets Layer (SSL)) ,SSL 是一种安全协议,它为网络(例如因特网)的通信提供私密性。SSL 使应用程序在通信时不用担心被窃听和篡改。 SSL 实际上 是共同工作的两个协议:“SSL 记录协议”(SSL Record Protocol)和“SSL 握手协议” (SSL Handshake Protocol)。“SSL 记录协议”是两个协议中较低级别的协议,它为较高级别的协议, 例如 SSL 握手协议对 数据的变长的记录进行加密和解密。SSL 握手协议处理应用程序凭证的交换和验证。
|
||||
|
||||
当一个应用程序(客户机)想和另一个应用程 序(服务器)通信时,客户机打开一个与服务器相连接的套接字连接。然后, 客户机和服务器对安全连接进行协商。作为协商的一部分,服务器向客户机作自我认 证。客户机可以选择向服务器**作或不作**自我认证。 一旦完成了认证并且建立了安全连接,则两个应用程序就可以安全地进行通信。按照惯例,我将把发起该通信的 对等机看作客户机, 另一个对等机则看作服务器,不管连接之后它们充当什么角色。
|
||||
|
||||
名为 A 和 B 的两台对等机想安全地进行通 信。在我们简单的 p2p 应用程序的环境中,对等机 A 想查询对等机 B 上的一个资源。 每个对等机都有__包含其专用密钥的一个数据库(名为 keystore)和包含其公用密钥的证书__。密码保护数据库的内容。 该数据库还包含一个或多个来自被信任的对等机的自签名证书。 对等机 A 发起这 项事务,每台对等机相互认证,两台对等机协商采用的密码及其长度并建立一个安全通道。完成这些操作之后, 每个对等机都知道它正在跟谁交谈并且知道通道是 安全的。 SSL (Secure socket Layer)安全套接层协议主要是使用公开密钥体制和X.509数字证书技术保护信息传输的机密性和完 整性, 它不能保证信息的不可抵赖性,主要适用于点对点之间的信息传输,常用Web Server方式。
|
||||
|
||||
安全套接层协议(SSL,Security Socket Layer)是网景(Netscape)公司提出的基于WEB应用的安全协议,它包括:服务器认证、 客户认证(可选)、SSL链路上的数据
|
||||
|
||||
完整性和SSL链路上的数据保密性。对于电子商务应用来说,使用SSL可保证信息的真实性、 完整性和保密性。但由于SSL不对应用层的消息进行数字签 名,因此不能提供交易的不可否认性,这是SSL在电子商务中使用的最大不足。 有鉴于此,网景公司在从Communicator 4.04版开始的所有浏 览器中引入了一种被称作“表单签名(Form Signing)”的功能, 在电子商务中,可利用这一功能来对包含购买者的订购信息和付款指令的表单进行 数字签名,从而保证交易信息的不可否认性。综上所述, 在电子商务中采用单一的SSL协议来保证交易的安全是不够的,但采用"SSL+表单签名"模式能够 为电子商务提供较好的安全性保证。
|
||||
41
Zim/Utils/SSH_and_SSL/SSL_and_TLS.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-10-12T19:25:44+08:00
|
||||
|
||||
====== SSL and TLS ======
|
||||
Created Wednesday 12 October 2011
|
||||
|
||||
SSL stands for "**Secure Sockets Layer;**" TLS, for "**Transport Layer Security.**" SSL was developed by Netscape for use in __securing HTTP.__ That is still its principal use, although there is nothing specific to HTTP about SSL. When a browser accesses a URL which begins with__ "https"__, it __speaks HTTP over an SSL connection__. TLS is the name of the IETF protocol standard that grew out of __SSL 3.0__, and is documented by RFC 2246. We will use the term "TLS."
|
||||
|
||||
TLS has goals and features similar to those of the SSH Transport and User Authentication protocols. It provides a single,__ full-duplex byte stream__ to clients, with cryptographically assured privacy and integrity, and optional authentication. It differs from SSH in the following principal ways:
|
||||
|
||||
TLS server authentication is optional: the protocol supports fully anonymous operation, in which neither side is authenticated. Such connections are inherently vulnerable to man-in-the-middle attacks. In SSH-TRANS, server authentication is mandatory, which protects against such attacks. Of course, it is always possible for a client to skip the step of verifying that the public key supplied by the server actually belongs to the entity the client intended to contact (e.g. using the **/etc/ssh_known_hosts** file). However, SSH-TRANS at least demands going through the motions.
|
||||
Both client and server authentication are done with X.509 public-key certificates. This makes TLS a bit more cumbersome to use than SSH in practice, since it requires a functioning __public-key infrastructure (PKI)__ to be in place, and certificates are more complicated things to generate and manage than SSH keys. However, a PKI system provides scalable key management for your trouble, which SSH currently lacks.
|
||||
TLS does not provide the range of client authentication options that SSH does; public-key is the only option.
|
||||
TLS does not have the extra features provided by the other SSH component: the SSH Connection Protocol (SSH-CONN). SSH-CONN uses the underlying SSH-TRANS connection to provide muliple logical data channels to the application, as well as support for remote program execution, terminal management, tunnelled TCP connections, flow control, etc.
|
||||
|
||||
|
||||
|
||||
====== SSL: ======
|
||||
A public key cryptography tunneling protocol, and various internet
|
||||
services can be piped through it. Ports 115, 563, 995, 465, and 443 are
|
||||
the standard ports for __SSL-encrypted FTP, NNTP, POP3, SMTP, and HTTP__
|
||||
sessions. Some clients have SSL support built-in (all web browsers, and
|
||||
some NNTP and e-mail clients). Clients without built-in SSL support can
|
||||
still use SSL via "**SSL proxies**" like Stunnel (i.e. Eudora@127.0.0.1 -->
|
||||
127.0.0.1:stunnel_port --> smtp.myisp.com:465). To my knowledge, there
|
||||
is __no username/password __authentication built into the SSL protocol itself.
|
||||
Authentication is left up to the daemon receiving __SSL connections.__ I.e.,
|
||||
if connecting to an NNTP server on port 563, user authentication would
|
||||
happen *inside the SSL tunnel* with the normal NNTP "AUTHINFO" commands,
|
||||
just like if a non-SSL port 119 NNTP connection were underway.
|
||||
|
||||
====== SSH: ======
|
||||
Another public key cryptography tunneling protocol like SSL, but
|
||||
unlike SSL, SSH__ has username/password authentication__ is built into it.
|
||||
All SSH-capable clients connect to port 22 (SSH) on the destination server
|
||||
to negotiate the username/password stage, and if successful, the clients
|
||||
then tell the SSH daemons what it wants to connect to. I.e., an SSH-aware
|
||||
SMTP client would connect to mail.myisp.com:22, send my username/password
|
||||
to the SSH daemon, and then tell the SSH daemon "I want you to connect to
|
||||
mail.myisp.com:25 on my behalf and proxy it through to me".
|
||||
248
Zim/Utils/VIM.txt
Normal file
@@ -0,0 +1,248 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-03-27T19:51:24+08:00
|
||||
|
||||
====== VIM ======
|
||||
Created Sunday 27 March 2011
|
||||
|
||||
14.vim打开txt文件中文乱码
|
||||
vim /etc/vimrc (加入4行)
|
||||
set fileencodings=utf-8,gb2312,gbk,gb18030
|
||||
set termencoding=utf-8
|
||||
set fileformats=unix
|
||||
set encoding=prc
|
||||
|
||||
/**
|
||||
*Useful usage of vim
|
||||
*Author: geekard
|
||||
*Date: 2011.3.6
|
||||
*Ver: 0.1
|
||||
*/
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
. repeat last change
|
||||
^ move curse to the first none space char of the line.
|
||||
0 move curse to the head of line
|
||||
$ move curse to the end of line
|
||||
* move curse to the next word of current curse on.
|
||||
# move curse to the prive word of current curse on.
|
||||
g* like * but match whole string which include the word.
|
||||
g# like #
|
||||
gd move curse to the current word in the none-note part.
|
||||
% move curse to other part of ([{
|
||||
u undo
|
||||
~ make current char to upper
|
||||
v toggle on VISUAL mode
|
||||
[n]>> shift current line to next n tabs position
|
||||
[n]<< shift current line to prive tabs position
|
||||
:#,#>
|
||||
:#,#<
|
||||
J connect two line together
|
||||
ctl+o move back to last positon
|
||||
ctl+i move foward to next postion
|
||||
ctl+[ shit to comnandmod
|
||||
ctl+] toggle help link
|
||||
ctl+v block select
|
||||
ctl+r redo
|
||||
ctl+p prive item
|
||||
ctl+n next item (using for command completation)
|
||||
ctl+d list all possible command (using for last-line mode)
|
||||
ctl+g display the edit stats
|
||||
ctl+w h j k l move curse between each window
|
||||
ctl+w q close current window
|
||||
ctl+a increase currnt number
|
||||
TAB command completation
|
||||
"a the register named a
|
||||
ma mark a position named a
|
||||
qa record the operations, quotaing as a
|
||||
@a replay the operations named a
|
||||
:edit open a file in current window
|
||||
:ab[revate] abrevate somewords in inserting mode
|
||||
:mksession name_of_session_file
|
||||
:new new window
|
||||
|
||||
Many commands that change text are made from an operator and a motion.
|
||||
The format for a delete command with the d delete operator is as follows:
|
||||
|
||||
d motion
|
||||
A short list of motions:
|
||||
w - until the start of the next word, EXCLUDING its first character.
|
||||
e - to the end of the current word, INCLUDING the last character.
|
||||
$ - to the end of the line, INCLUDING the last character.
|
||||
|
||||
Thus typing de will delete from the cursor to the end of the word.
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
1. To delete from the cursor up to the next word type: dw
|
||||
2. To delete from the cursor to the end of a line type: d$
|
||||
3. To delete a whole line type: dd
|
||||
|
||||
4. To repeat a motion prepend it with a number: 2w
|
||||
5. The format for a change command is:
|
||||
operator [number] motion
|
||||
where:
|
||||
operator - is what to do, such as d for delete
|
||||
[number] - is an optional count to repeat the motion
|
||||
motion - moves over the text to operate on, such as w (word),
|
||||
$ (to the end of line), etc.
|
||||
|
||||
6. To move to the start of the line use a zero: 0
|
||||
|
||||
7. To undo previous actions, type: u (lowercase u)
|
||||
To undo all the changes on a line, type: U (capital U)
|
||||
To the undo's, type: CTRL-R
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lesson 4 SUMMARY
|
||||
|
||||
|
||||
1. CTRL-G displays your location in the file and the file status.
|
||||
G moves to the end of the file.
|
||||
number G moves to that line number.
|
||||
gg moves to the first line.
|
||||
|
||||
2. Typing / followed by a phrase searches FORWARD for the phrase.
|
||||
Typing ? followed by a phrase searches BACKWARD for the phrase.
|
||||
After a search type n to find the next occurrence in the same direction
|
||||
or N to search in the opposite direction.
|
||||
CTRL-O takes you back to older positions, CTRL-I to newer positions.
|
||||
|
||||
3. Typing % while the cursor is on a (,),[,],{, or } goes to its match.
|
||||
|
||||
4. To substitute new for the first old in a line type :s/old/new
|
||||
To substitute new for all 'old's on a line type :s/old/new/g
|
||||
To substitute phrases between two line #'s type :#,#s/old/new/g
|
||||
To substitute all occurrences in the file type :%s/old/new/g
|
||||
To ask for confirmation each time add 'c' :%s/old/new/gc
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lesson 5.3: SELECTING TEXT TO WRITE
|
||||
|
||||
|
||||
** To save part of the file, type v motion :w FILENAME **
|
||||
|
||||
1. Move the cursor to this line.
|
||||
|
||||
2. Press v and move the cursor to the fifth item below. Notice that the
|
||||
text is highlighted.
|
||||
|
||||
3. Press the : character. At the bottom of the screen :'<,'> will appear.
|
||||
|
||||
4. Type w TEST , where TEST is a filename that does not exist yet. Verify
|
||||
that you see :'<,'>w TEST before you press <ENTER>.
|
||||
|
||||
5. Vim will write the selected lines to the file TEST. Use :!dir or !ls
|
||||
to see it. Do not remove it yet! We will use it in the next lesson.
|
||||
|
||||
NOTE: Pressing v starts Visual selection. You can move the cursor around
|
||||
to make the selection bigger or smaller. Then you can use an operator
|
||||
to do something with the text.
|
||||
|
||||
|
||||
For example, d deletes the text;
|
||||
s/^/# add # to begin of each line.
|
||||
[n]> right shift n times
|
||||
|
||||
|
||||
|
||||
6. :r FILENAME retrieves disk file FILENAME and puts it below the
|
||||
cursor position.
|
||||
|
||||
7. :r !ls reads the output of the dir command and puts it below the
|
||||
cursor position.
|
||||
NOTE: a, i and A all go to the same Insert mode, the only difference is where
|
||||
the characters are inserted.
|
||||
NOTE: Replace mode(R) is like Insert mode, but every typed character deletes an
|
||||
existing character.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lesson 6 SUMMARY
|
||||
|
||||
1. Type o to open a line BELOW the cursor and start Insert mode.
|
||||
Type O to open a line ABOVE the cursor.
|
||||
|
||||
2. Type a to insert text AFTER the cursor.
|
||||
Type A to insert text after the end of the line.
|
||||
|
||||
3. The e command moves to the end of a word.
|
||||
|
||||
4. The y operator yanks (copies) text, p puts (pastes) it.
|
||||
|
||||
5. Typing a capital R enters Replace mode until <ESC> is pressed.
|
||||
|
||||
6. Typing ":set xxx" sets the option "xxx". Some options are:
|
||||
'ic' 'ignorecase' ignore upper/lower case when searching
|
||||
'is' 'incsearch' show partial matches for a search phrase
|
||||
'hls' 'hlsearch' highlight all matching phrases
|
||||
You can either use the long or the short option name.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lesson 7.2: CREATE A STARTUP SCRIPT
|
||||
|
||||
|
||||
** Enable Vim features **
|
||||
|
||||
Vim has many more features than Vi, but most of them are disabled by
|
||||
default. To start using more features you have to create a "vimrc" file.
|
||||
|
||||
1. Start editing the "vimrc" file. This depends on your system:
|
||||
:e ~/.vimrc for Unix
|
||||
:e $VIM/_vimrc for MS-Windows
|
||||
|
||||
2. Now read the example "vimrc" file contents:
|
||||
:r $VIMRUNTIME/vimrc_example.vim
|
||||
|
||||
3. Write the file with:
|
||||
:w
|
||||
|
||||
The next time you start Vim it will use syntax highlighting.
|
||||
You can add all your preferred settings to this "vimrc" file.
|
||||
For more information type :help vimrc-intro
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lesson 7.3: COMPLETION
|
||||
|
||||
|
||||
** Command line completion with CTRL-D and <TAB> **
|
||||
|
||||
1. Make sure Vim is not in compatible mode: :set nocp
|
||||
|
||||
2. Look what files exist in the directory: :!ls or :!dir
|
||||
|
||||
3. Type the start of a command: :e
|
||||
|
||||
4. Press CTRL-D and Vim will show a list of commands that start with "e".
|
||||
|
||||
5. Press <TAB> and Vim will complete the command name to ":edit".
|
||||
|
||||
6. Now add a space and the start of an existing file name: :edit FIL
|
||||
|
||||
7. Press <TAB>. Vim will complete the name (if it is unique).
|
||||
|
||||
NOTE: Completion works for many commands. Just try pressing CTRL-D and
|
||||
<TAB>. It is especially useful for :help .
|
||||
|
||||
7. Prepend "no" to switch an option off: :set noic
|
||||
|
||||
set tabstop=4 set real tab-space to 4 not default 8
|
||||
set stabstop=4 when press tab ,curse move 4 space
|
||||
set shiftwidth=4 auto shift 4 spaces
|
||||
set nu
|
||||
set ai or set autoindent
|
||||
set fileencoding=cp936 utf-8
|
||||
:help options give a complete list of all options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Lesson 7 SUMMARY
|
||||
|
||||
|
||||
1. Type :help or press <F1> or <Help> to open a help window.
|
||||
|
||||
2. Type :help cmd to find help on cmd .
|
||||
|
||||
|
||||
3. Type CTRL-W CTRL-W to jump to another window
|
||||
|
||||
4. Type :q to close the help window
|
||||
|
||||
5. Create a vimrc startup script to keep your preferred settings.
|
||||
|
||||
6. When typing a : command, press CTRL-D to see possible completions.
|
||||
Press <TAB> to use one completion.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
63
Zim/Utils/alsa.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-13T12:36:35+08:00
|
||||
|
||||
====== alsa ======
|
||||
Created Saturday 13 August 2011
|
||||
|
||||
===== Installation =====
|
||||
|
||||
**ALSA **is included in the default Arch kernel as a set of modules, so installing it isn't necessary.
|
||||
|
||||
**udev **will automatically __probe your hardware__ at boot, loading the corresponding kernel module for your audio card. Therefore, your sound should already be working, but upstream sources __mute__ all channels by default.
|
||||
|
||||
Users must be in the __audio__ group to play sound with ALSA. To add a user to the audio group, use the following command:
|
||||
# __gpasswd__ -a yourusername audio
|
||||
|
||||
===== User-space utilities =====
|
||||
|
||||
The__ alsa-utils __package contains the **alsamixer** userspace tool, which allows configuration of the sound device from the console or terminal. Install it with pacman:
|
||||
# pacman -S alsa-utils
|
||||
|
||||
Install the __alsa-oss__ package if you want OSS applications to work with dmix (software mixing):
|
||||
# pacman -S alsa-oss
|
||||
|
||||
Install the __alsa-plugins __package if you want high quality resampling, upmixing/downmixing and other advanced features:
|
||||
# pacman -S alsa-plugins
|
||||
|
||||
===== Unmuting the channels =====
|
||||
|
||||
The current version of ALSA installs with **all channels muted by default**. You will need to unmute the channels manually.
|
||||
|
||||
It is easiest to use alsamixer ncurses UI to accomplish this (alternatively, use amixer from the commandline):
|
||||
$ alsamixer
|
||||
|
||||
The label "MM" below a channel indicates that the channel is muted, and "00" indicates that it is open.
|
||||
|
||||
Unmute the Master and PCM channels by scrolling to them with cursor left/right and pressing M. Use the ↑ key to increase the volume and obtain a value of zero dB gain. The gain may be found in the upper left next to the 'Item:' field. Higher values of gain will produce distorted sound.
|
||||
|
||||
To get full 5.1 or 7.1 surround sound you likely need to unmute other channels such as Front, Surround, Center, LFE (subwoofer) and Side (these are the names of the channels with Intel HD Audio, they may vary with different hardware). Please take note that this will not automatically upmix stereo sources (like most music). In order to accomplish that, see #Upmixing/Downmixing.
|
||||
|
||||
Leave alsamixer by pressing Esc.
|
||||
Note: Some cards need to have digital output muted/turned off in order to hear analog sound. For the Soundblaster Audigy LS mute the IEC958 channel.
|
||||
Note: Some machines, (like the Thinkpad T61), have a Speaker channel which must be unmuted and adjusted as well.
|
||||
|
||||
Next, test to see if sound works:
|
||||
$ __speaker-test __-c 2
|
||||
|
||||
Change -c to fit your speaker setup. Use -c 8 for 7.1, for instance:
|
||||
$ speaker-test -c 8
|
||||
|
||||
If it doesn't work, proceed to #Configuration and then #Troubleshooting to solve your issues.
|
||||
|
||||
If it works, you just need to save your mixer settings.
|
||||
# __alsactl__ -f /var/lib/alsa/asound.state store
|
||||
|
||||
This will create the file /var/lib/alsa/asound.state, saving the alsamixer settings.
|
||||
|
||||
Then, add__ the alsa daemon__ to your DAEMONS section in /etc/rc.conf to automatically **restore the mixer settings **at boot.
|
||||
File: /etc/rc.conf
|
||||
|
||||
DAEMONS=(... @alsa ...)
|
||||
|
||||
Note: The alsa daemon merely restores your volume mixer levels on boot up by reading** /var/lib/alsa/asound.state**. It is separate from the alsa audio library (and kernel level API).
|
||||
7
Zim/Utils/apache.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-23T13:27:08+08:00
|
||||
|
||||
====== apache ======
|
||||
Created Monday 23 May 2011
|
||||
|
||||
39
Zim/Utils/apache/源码编译apache,让它支持ssl.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-10T17:20:03+08:00
|
||||
|
||||
====== 源码编译apache,让它支持ssl ======
|
||||
Created Wednesday 10 August 2011
|
||||
|
||||
1、 了解系统有没有安装openssl,应该默认都安装了。
|
||||
2、 生成ssl证书
|
||||
openssl genrsa -des3 -out ssl.key 1024
|
||||
然后他会要求你输入这个key文件的密码。不推荐输入。因为以后要给apache使用。
|
||||
由于生成时候必须输入密码。你可以输入后 再删掉。
|
||||
mv ssl.key xxx.key
|
||||
openssl rsa -in xxx.key -out ssl.key
|
||||
rm xxx.key
|
||||
然后根据这个key文件生成证书请求文件
|
||||
openssl req -new -key ssl.key -out ssl.csr
|
||||
|
||||
最后根据这2个文件生成crt证书文件
|
||||
openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
|
||||
|
||||
最后用到的文件是key和crt文件。
|
||||
|
||||
3、 tar zxvf httpd-2.2.10.tar.gz
|
||||
|
||||
4、 cd httpd-2.2.10
|
||||
|
||||
5、 ./configure –prefix=/usr/local/apache –enable-ssl && make && make install
|
||||
|
||||
6、 vi /usr/local/apache/conf/extra/httpd-ssl.conf
|
||||
修改以下两项,将openssl生成的证书cp到相应路径(/usr/local/apache/conf/)
|
||||
SSLCertificateFile "/usr/local/apache/conf/ssl.crt"
|
||||
SSLCertificateKeyFile "/usr/local/apache/conf/ssl.key"
|
||||
|
||||
7、vi /usr/local/apache/conf/httpd.conf
|
||||
去掉这行注释
|
||||
Include conf/extra/httpd-ssl.conf
|
||||
|
||||
8、/usr/local/apache/bin/apachectl start
|
||||
1731
Zim/Utils/apache/详解.txt
Normal file
243
Zim/Utils/autoconf---automake.txt
Normal file
@@ -0,0 +1,243 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-22T17:07:57+08:00
|
||||
|
||||
====== autoconf---automake ======
|
||||
Created Thursday 22 December 2011
|
||||
http://www.ibm.com/developerworks/cn/linux/l-makefile/
|
||||
|
||||
===== 引子 =====
|
||||
|
||||
无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或 make install。利用make工具,我们可以将**大型的开发项目分解成为多个更易于管理的模块**,对于一个包括几百个源文件的应用程序,使用make和 makefile工具就可以轻而易举的理顺各个**源文件之间纷繁复杂的相互关系**。
|
||||
|
||||
但是如果通过查阅make的帮助文档来**手工编写Makefile**,对任何程序员都是一场挑战。幸而有GNU 提供的Autoconf及Automake这两套工具使得编写makefile不再是一个难题。
|
||||
|
||||
本文将介绍如何利用 GNU Autoconf 及 Automake 这两套工具来协助我们**自动产生 Makefile文件**,并且让开发出来的软件可以像大多数源码包那样,只需"./configure", "make","make install" 就可以把程序安装到系统中。
|
||||
|
||||
|
||||
===== 模拟需求 =====
|
||||
|
||||
假设源文件按如下目录存放,如图1所示,运用autoconf和automake生成makefile文件。
|
||||
|
||||
图 1文件目录结构
|
||||
{{./1.jpg}}
|
||||
|
||||
|
||||
假设src是我们源文件目录,include目录存放其他库的头文件,lib目录存放用到的库文件,然后开始按模块存放,每个模块都有一个对应的目录,**模块下再分子模块**,如apple、orange。每个子目录下又分core,include,shell三个目录,其中core和shell目录存放.c文件,include的存放.h文件,其他类似。
|
||||
样例程序功能:基于多线程的数据读写保护(联系作者获取整个autoconf和automake生成的Makefile工程和源码,E-mail:normalnotebook@126.com)。
|
||||
|
||||
===== 工具简介 =====
|
||||
|
||||
所必须的软件:autoconf/automake/m4/perl/libtool(其中libtool非必须)。
|
||||
|
||||
autoconf是一个用于生成可以**自动地配置软件源码包,用以适应多种UNIX类系统的shell脚本工具**,其中autoconf需要用到 m4,便于生成脚本。automake是一个**从Makefile.am文件自动生成Makefile.in的工具**。为了生成Makefile.in,automake还需用到perl,由于automake创建的发布完全遵循GNU标准,所以在创建中不需要perl。libtool是一款方便生成各种程序库的工具。
|
||||
|
||||
目前automake支持**三种目录层次**:flat、shallow和deep。
|
||||
|
||||
1) flat指的是所有文件都位于同一个目录中。
|
||||
|
||||
就是所有源文件、头文件以及其他库文件都位于当前目录中,且**没有子目录**。Termutils就是这一类。
|
||||
|
||||
2) shallow指的是主要的源代码都储存在顶层目录,其他各个部分则储存在子目录中。
|
||||
|
||||
就是主要源文件在当前目录中,而其它一些**实现各部分功能**的源文件位于各自不同的目录。automake本身就是这一类。
|
||||
|
||||
3) deep指的是所**有源代码都被储存在子目录中;顶层目录主要包含配置信息**。
|
||||
|
||||
就是所有源文件及自己写的头文件位于当前目录的一个子目录中,而当前目录里没有任何源文件。 GNU cpio和GNU tar就是这一类。
|
||||
|
||||
flat类型是最简单的,deep类型是最复杂的。不难看出,我们的模拟需求正是基于第三类deep型,也就是说我们要做挑战性的事情:)。注:我们的测试程序是基于多线程的简单程序。
|
||||
|
||||
|
||||
===== 生成 Makefile 的来龙去脉 =====
|
||||
|
||||
首先进入 project 目录,在该目录下运行一系列命令,创建和修改几个文件,就可以生成符合**该平台**的Makefile文件,操作过程如下:
|
||||
1) 运行autoscan命令
|
||||
2) 将configure.scan 文件重命名为configure.in,并修改configure.in文件
|
||||
3) 在**project目录**下新建Makefile.am文件,并在**core和shell**目录下也新建makefile.am文件
|
||||
4) 在project目录下新建NEWS、 README、 ChangeLog 、AUTHORS文件
|
||||
5) 将/usr/share/automake-1.X/目录下的depcomp和complie文件拷贝到本目录下
|
||||
6) 运行aclocal命令
|
||||
7) 运行autoconf命令
|
||||
8) 运行automake -a命令
|
||||
9) 运行**./confiugre**脚本
|
||||
|
||||
可以通过图2看出产生Makefile的流程,如图所示:
|
||||
|
||||
图 2生成Makefile流程图
|
||||
{{./2.gif}}
|
||||
|
||||
|
||||
===== Configure.in的八股文(整个工程只需一个该文件) =====
|
||||
|
||||
当我们利用autoscan工具生成confiugre.scan文件时,我们需要将confiugre.scan重命名为confiugre.in文件。confiugre.in调用__一系列autoconf宏__来测试程序需要的或用到的__特性__是否存在以及这些特性的功能。
|
||||
|
||||
下面我们就来目睹一下confiugre.scan的庐山真面目:
|
||||
|
||||
# Process this file with autoconf to produce a **configure script**.
|
||||
AC_PREREQ(2.59)
|
||||
**AC_INIT**(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
||||
AC_CONFIG_SRCDIR([config.h.in])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
# Checks for libraries.
|
||||
# FIXME: Replace `main' with a function in `-lpthread':
|
||||
AC_CHECK_LIB([pthread], [main]) #main为在库pthread中检查的函数名。
|
||||
# Checks for header files.
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
# Checks for library functions.
|
||||
**AC_OUTPUT**
|
||||
#上述所有的[]中的内容需要自定义。
|
||||
每个configure.scan文件都是以AC_INIT开头,以AC_OUTPUT结束。我们不难从文件中看出confiugre.in文件的一般布局:
|
||||
|
||||
AC_INIT
|
||||
测试程序
|
||||
测试函数库
|
||||
测试头文件
|
||||
测试类型定义
|
||||
测试结构
|
||||
测试编译器特性
|
||||
测试库函数
|
||||
测试系统调用
|
||||
AC_OUTPUT
|
||||
|
||||
|
||||
上面的调用次序只是**建议性质**的,但我们还是强烈建议不要随意改变对宏调用的__次序__。
|
||||
|
||||
现在就开始修改该文件:
|
||||
|
||||
$mv configure.scan configure.in
|
||||
$vim configure.in
|
||||
|
||||
|
||||
修改后的结果如下:
|
||||
|
||||
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.59)
|
||||
**AC_INIT**(test, 1.0, normalnotebook@126.com)
|
||||
AC_CONFIG_**SRCDIR**([src/ModuleA/apple/core/test.c])
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
**AM_INIT_AUTOMAKE**(test,1.0)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
# Checks for libraries.
|
||||
# FIXME: Replace `main' with a function in `-lpthread':
|
||||
AC_CHECK_LIB([pthread], [**pthread_rwlock_init**]) #库中的函数名称
|
||||
AC_PROG___RANLIB__
|
||||
# Checks for header files.
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
# Checks for library functions.
|
||||
**AC_OUTPUT**([Makefile #当前项目根目录
|
||||
src/lib/Makefile
|
||||
src/ModuleA/apple/core/Makefile
|
||||
src/ModuleA/apple/shell/Makefile
|
||||
])
|
||||
|
||||
|
||||
|
||||
其中要将AC_CONFIG_HEADER([config.h])修改为:AM_CONFIG_HEADER(**config.h**), 并加入AM_INIT_AUTOMAKE(test,1.0)。由于我们的测试程序是基于多线程的程序,所以要加入AC_PROG_RANLIB,不然运行automake命令时会出错。在AC_OUTPUT输入要创建的Makefile文件名。
|
||||
|
||||
由于我们在程序中使用了读写锁,所以需要对**库文件**进行检查,即AC_CHECK_LIB([pthread], [main]),该宏的含义如下:
|
||||
{{./3.gif}}
|
||||
其中,LIBS是link的一个选项,详细请参看后续的Makefile文件。由于我们在程序中使用了读写锁,所以我们测试**pthread库中是否存在pthread_rwlock_init函数**。
|
||||
|
||||
由于我们是基于deep类型来创建makefile文件,所以我们需要在**四处创建Makefile文件**。即:project目录下,lib目录下,core和shell目录下。
|
||||
|
||||
Autoconf提供了很多__内置宏来做相关的检测__,限于篇幅关系,我们在这里对其他宏不做详细的解释,具体请参看参考文献1和参考文献2,也可参看autoconf信息页。
|
||||
|
||||
|
||||
===== 实战Makefile.am =====
|
||||
|
||||
Makefile.am是一种**比Makefile更高层次的规则**。只需指定要__生成什么__目标,它由__哪些源文件__生成,要__安装到__什么目录等构成。
|
||||
|
||||
表一列出了可执行文件、静态库、头文件和数据文件,四种书写Makefile.am文件个一般格式。
|
||||
|
||||
表 1Makefile.am一般格式
|
||||
{{./4.gif}}
|
||||
|
||||
对于可执行文件和静态库类型,如果只想编译,不想安装到系统中,可以用**noinst_PROGRAMS**代替bin_PROGRAMS,**noinst_LIBRARIES**代替lib_LIBRARIES。
|
||||
|
||||
Makefile.am还提供了一些**全局变量**供所有的目标体使用:
|
||||
|
||||
表 2 Makefile.am中可用的全局变量
|
||||
{{./5.gif}}
|
||||
|
||||
在Makefile.am中__尽量使用相对路径__,系统预定义了两个基本路径:
|
||||
|
||||
表 3Makefile.am中可用的路径变量
|
||||
{{./6.gif}}
|
||||
|
||||
在上文中我们提到过安装路径,automake设置了默认的安装路径:
|
||||
|
||||
1) 标准安装路径
|
||||
|
||||
默认安装路径为:$(prefix) = /usr/local,可以通过./configure **--prefix**=<new_path>的方法来覆盖。
|
||||
其它的预定义目录还包括:bindir = $(prefix)/bin, libdir = $(prefix)/lib, **datadir** = $(prefix)/share, **sysconfdir** = $(prefix)/etc等等。
|
||||
|
||||
2) 定义一个新的安装路径
|
||||
|
||||
比如test, 可定义testdir = $(prefix)/test, 然后test_DATA =test1 test2,则test1,test2会作为数据文件安装到$(prefix)/test目录下。
|
||||
我们首先需要在工程顶层目录下(即project/)创建一个Makefile.am来指明包含的子目录:
|
||||
|
||||
__SUBDIRS__=src/lib src/ModuleA/apple/shell src/ModuleA/apple/core
|
||||
**CURRENTPATH**=$(shell /bin/pwd)
|
||||
**INCLUDES=**-I$(CURRENTPATH)/src/include -I$(CURRENTPATH)/src/ModuleA/apple/include
|
||||
**export **INCLUDES
|
||||
|
||||
|
||||
由于每个源文件都会用到相同的头文件,所以我们在最顶层的Makefile.am中包含了编译源文件时所用到的头文件,并导出,见蓝色部分代码。
|
||||
|
||||
我们将lib目录下的swap.c文件编译成libswap.a文件,被apple/shell/apple.c文件调用,那么lib目录下的Makefile.am如下所示:
|
||||
|
||||
**noinst**_LIBRARIES=__libswap.a__
|
||||
libswap_a_SOURCES=swap.c
|
||||
INCLUDES=-I**$(top_srcdir)**/src/includ
|
||||
|
||||
|
||||
细心的读者可能就会问:怎么表1中给出的是bin_LIBRARIES,而这里是noinst_LIBRARIES?这是因为如果只想编译,而不想安装到系统中,就用noinst_LIBRARIES代替bin_LIBRARIES,对于可执行文件就用noinst_PROGRAMS代替bin_PROGRAMS。对于安装的情况,库将会安装到$(prefix)/lib目录下,可执行文件将会安装到${prefix}/bin。如果想安装该库,则Makefile.am示例如下:
|
||||
|
||||
bin_LIBRARIES=libswap.a
|
||||
libswap_a_SOURCES=swap.c
|
||||
INCLUDES=-I$(top_srcdir)/src/include
|
||||
**swapincludedir=**$(includedir)/swap #自定义的一个变量
|
||||
**swapinclude_HEADERS**=$(top_srcdir)/src/include/**swap.h**
|
||||
|
||||
|
||||
最后两行的意思是将swap.h安装到${prefix}/include /swap目录下。
|
||||
|
||||
接下来,对于**可执行文件类型**的情况,我们将讨论如何写Makefile.am?对于编译apple/core目录下的文件,我们写成的Makefile.am如下所示:
|
||||
|
||||
noinst_PROGRAMS=test
|
||||
test_SOURCES=test.c
|
||||
test_**LDADD**=$(top_srcdir)/src/ModuleA/apple/shell/**apple.o** $(top_srcdir)/src/lib/libswap.a
|
||||
test_**LDFLAGS**=-D_GNU_SOURCE
|
||||
DEFS+=-D_GNU_SOURCE
|
||||
#__LIBS__=-lpthread
|
||||
|
||||
|
||||
由于我们的test.c文件在**链接时**,需要apple.o和libswap.a文件,所以我们需要在test_LDADD中包含这两个文件。对于Linux下的信号量/读写锁文件进行编译,需要在编译选项中指明-D_GNU_SOURCE。所以在test_LDFLAGS中指明。而test_LDFLAGS只是链接时的选项,**编译时同样需要指明该选项**,所以需要__DEFS来指明编译选项__,由于DEFS**已经有初始值**,所以这里用+=的形式指明。从这里可以看出,Makefile.am中的语法与Makefile的语法一致,也可以采用条件表达式。如果你的程序还包含其他的库,除了用AC_CHECK_LIB宏来指明外,还可以用LIBS来指明。
|
||||
|
||||
如果你只想编译某一个文件,那么Makefile.am如何写呢?这个文件也很简单,写法跟可执行文件的差不多,如下例所示:
|
||||
|
||||
noinst_PROGRAMS=apple
|
||||
apple_SOURCES=apple.c
|
||||
DEFS+=-D_GNU_SOURCE
|
||||
|
||||
|
||||
我们这里只是欺骗automake,假装要生成apple文件,让它为我们**生成依赖关系和执行命令**。所以当你运行完automake命令后,然后修改apple/shell/下的**Makefile.in**文件,直接将LINK语句删除,即:
|
||||
|
||||
…….
|
||||
clean-noinstPROGRAMS:
|
||||
-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
|
||||
apple$(EXEEXT): $(apple_OBJECTS) $(apple_DEPENDENCIES)
|
||||
@rm -f apple$(EXEEXT)
|
||||
#$(LINK) $(apple_LDFLAGS) $(apple_OBJECTS) $(apple_LDADD) $(LIBS)
|
||||
…….
|
||||
|
||||
|
||||
通过上述处理,就可以达到我们的目的。从图1中不难看出为什么要修改Makefile.in的原因,而不是修改其他的文件。
|
||||
BIN
Zim/Utils/autoconf---automake/1.jpg
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
Zim/Utils/autoconf---automake/2.gif
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
Zim/Utils/autoconf---automake/3.gif
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
Zim/Utils/autoconf---automake/4.gif
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Zim/Utils/autoconf---automake/5.gif
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Zim/Utils/autoconf---automake/6.gif
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
38
Zim/Utils/autoconf---automake/代码.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-12-22T22:26:12+08:00
|
||||
|
||||
====== 代码 ======
|
||||
Created Thursday 22 December 2011
|
||||
|
||||
=== Autoconf ===
|
||||
|
||||
|
||||
Autoconf (2.59):
|
||||
ftp://ftp.gnu.org/gnu/autoconf/
|
||||
|
||||
===== Autoconf的内容 =====
|
||||
|
||||
Autoconf 能生成用于自动配置源代码的 shell 脚本(**configure**),该脚本可以生成makefile文件。
|
||||
|
||||
安装下列程序: autoconf, autoheader, autom4te, autoreconf, autoscan, autoupdate 和 ifnames
|
||||
|
||||
===== 简短说明 =====
|
||||
|
||||
autoconf是一个产生可以自动配置源代码包,生成shell脚本的工具,以适应各种类UNIX系统的需要。autoconf 产生的配置脚本在运行时独立于autoconf ,因此使用这些脚本的用户不需要安装autoconf。
|
||||
|
||||
autoheader能够产生供configure脚本使用的C #define语句模板文件。
|
||||
|
||||
autom4te对文件执行 GNU M4。
|
||||
|
||||
autoreconf,如果有多个autoconf产生的配置文件,autoreconf可以保存一些工作,它通过重复运行autoconf(以及在合适的地方运行autoheader)以重新产生autoconf配置脚本和配置头模板,这些文件保存在以当前目录为根的目录树中。
|
||||
|
||||
autoscan程序可以用来为软件包创建configure.in文件。autoscan在以命令行参数中指定的目录为根(如果未给定参数,则以当前目录为根)的目录树中检查源文件。它为通常的轻便问题搜索源文件,并且为那个包创建一个configure.scan文件,这个文件就是configure.in的前身。
|
||||
|
||||
autoupdate程序将一个调用autoconf 宏的旧名称的configure.in文件中的宏更新为新的名称。
|
||||
|
||||
ifnames当为一个软件包写configure.in 时,ifnames可以提供一些帮助。它打印包中那些在C预处理器中已经使用了的表示符。如果一个包已经设置成具有某些可移植属性,这个程序能够帮助指出它的配置应该如何检查。它可以用来填补由autoscan产生的configure.in中的隔阂。
|
||||
|
||||
Autoconf 安装依赖关系
|
||||
|
||||
Autoconf 依赖于: Bash, Coreutils, Diffutils, Grep, M4, Make, Perl, Sed.
|
||||
14
Zim/Utils/blkid.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-03-27T19:11:36+08:00
|
||||
|
||||
====== blkid ======
|
||||
Created Sunday 27 March 2011
|
||||
|
||||
**blkid**
|
||||
|
||||
is a command utility to display block disk attributes
|
||||
|
||||
geekard@geekard-laptop:~$ sudo blkid /dev/sda3
|
||||
/dev/sda3: LABEL="/" UUID="18d7325c-ab28-4fca-95a9-a5b43cc0f839" TYPE="ext4"
|
||||
geekard@geekard-laptop:~$
|
||||
147
Zim/Utils/cron.txt
Normal file
@@ -0,0 +1,147 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-11-23T10:50:36+08:00
|
||||
|
||||
====== cron ======
|
||||
Created Wednesday 23 November 2011
|
||||
http://hi.baidu.com/sjh_forever/blog/item/6008e839e8cfef2fb9998f69.html
|
||||
2009-12-15 22:37
|
||||
|
||||
cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:
|
||||
|
||||
/sbin/service crond start //启动服务
|
||||
|
||||
/sbin/service crond stop //关闭服务
|
||||
|
||||
/sbin/service crond restart //重启服务
|
||||
|
||||
/sbin/service crond reload //重新载入配置
|
||||
|
||||
你也可以将这个服务在系统启动的时候自动启动:
|
||||
|
||||
在/etc/rc.d/rc.local这个脚本的末尾加上:
|
||||
|
||||
/sbin/service crond start
|
||||
|
||||
现在Cron这个服务已经在进程里面了,我们就可以用这个服务了,Cron服务提供以下几种接口供大家使用:
|
||||
|
||||
1.直接用crontab命令编辑
|
||||
|
||||
cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明:
|
||||
|
||||
crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数
|
||||
|
||||
crontab -l //列出某个用户cron服务的详细内容
|
||||
|
||||
crontab -r //删除没个用户的cron服务
|
||||
|
||||
crontab -e //编辑某个用户的cron服务
|
||||
|
||||
比如说root查看自己的cron设置:crontab -u root -l
|
||||
|
||||
再例如,root想删除fred的cron设置:crontab -u fred -r
|
||||
|
||||
在编辑cron服务时,编辑的内容有一些格式和约定,输入:crontab -u root -e
|
||||
|
||||
进入vi编辑模式,编辑的内容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt
|
||||
|
||||
任务调度的crond常驻命令
|
||||
crond 是linux用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。
|
||||
|
||||
1、linux任务调度的工作主要分为以下两类:
|
||||
*系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
|
||||
*个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置。
|
||||
|
||||
2.crontab命令选项:
|
||||
-u指定一个用户,
|
||||
-l列出某个用户的任务计划,
|
||||
-r删除某个用户的任务,
|
||||
-e编辑某个用户的任务
|
||||
|
||||
3.cron文件语法:
|
||||
分 小时 日 月 星期 命令
|
||||
0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)
|
||||
|
||||
4.记住几个特殊符号的含义:
|
||||
"*"代表取值范围内的数字,
|
||||
"/"代表"每",
|
||||
"-"代表从某个数字到某个数字,
|
||||
","分开几个离散的数字
|
||||
|
||||
一、任务调度设置文件的写法
|
||||
|
||||
可用crontab -e命令来编辑,编辑的是/var/spool/cron下对应用户的cron文件,也可以直接修改/etc/crontab文件
|
||||
具体格式如下:
|
||||
Minute Hour Day Month Dayofweek command
|
||||
分钟 小时 天 月 天每星期 命令
|
||||
|
||||
每个字段代表的含义如下:
|
||||
Minute 每个小时的第几分钟执行该任务
|
||||
Hour 每天的第几个小时执行该任务
|
||||
Day 每月的第几天执行该任务
|
||||
Month 每年的第几个月执行该任务
|
||||
DayOfWeek 每周的第几天执行该任务
|
||||
Command 指定要执行的程序
|
||||
在这些字段里,除了“Command”是每次都必须指定的字段以外,其它字段皆为可选字段,可视需要决定。对于不指定的字段,要用“*”来填补其位置。
|
||||
|
||||
举例如下:
|
||||
5 * * * * ls 指定每小时的第5分钟执行一次ls命令
|
||||
30 5 * * * ls 指定每天的 5:30 执行ls命令
|
||||
30 7 8 * * ls 指定每月8号的7:30分执行ls命令
|
||||
30 5 8 6 * ls 指定每年的6月8日5:30执行ls命令
|
||||
30 6 * * 0 ls 指定每星期日的6:30执行ls命令[注:0表示星期天,1表示星期1,以此类推,也可以用英文来表示,sun表示星期天,mon表示星期一等。]
|
||||
30 3 10,20 * * ls 每月10号及20号的3:30执行ls命令[注:“,”用来连接多个不连续的时段]
|
||||
25 8-11 * * * ls 每天8-11点的第25分钟执行ls命令[注:“-”用来连接连续的时段]
|
||||
*/15 * * * * ls 每15分钟执行一次ls命令 [即每个小时的第0 15 30 45 60分钟执行ls命令 ]
|
||||
30 6 */10 * * ls 每个月中,每隔10天6:30执行一次ls命令[即每月的1、11、21、31日是的6:30执行一次ls命令。 ]
|
||||
每天7:50以root 身份执行/etc/cron.daily目录中的所有可执行文件
|
||||
50 7 * * * root run-parts /etc/cron.daily [ 注:run-parts参数表示,执行后面目录中的所有可执行文件。 ]
|
||||
|
||||
二、新增调度任务
|
||||
|
||||
新增调度任务可用两种方法:
|
||||
1、在命令行输入: crontab -e 然后添加相应的任务,wq存盘退出。
|
||||
2、直接编辑/etc/crontab 文件,即vi /etc/crontab,添加相应的任务。
|
||||
|
||||
三、查看调度任务
|
||||
|
||||
crontab -l //列出当前的所有调度任务
|
||||
crontab -l -u jp //列出用户jp的所有调度任务
|
||||
|
||||
四、删除任务调度工作
|
||||
|
||||
crontab -r //删除所有任务调度工作
|
||||
|
||||
五、任务调度执行结果的转向
|
||||
|
||||
例1:每天5:30执行ls命令,并把结果输出到/jp/test文件中
|
||||
30 5 * * * ls >/jp/test 2>&1
|
||||
注:2>&1 表示执行结果及错误信息。
|
||||
|
||||
编辑/etc/crontab 文件配置cron
|
||||
|
||||
cron服务每分钟不仅要读一次/var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也 能运用cron服务做一些事情。用crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:
|
||||
|
||||
SHELL=/bin/bash
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号
|
||||
|
||||
HOME=/ //使用者运行的路径,这里是根目录
|
||||
|
||||
# run-parts
|
||||
|
||||
01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本
|
||||
|
||||
02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本
|
||||
|
||||
22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本
|
||||
|
||||
42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本
|
||||
|
||||
大家注意"run-parts"这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了
|
||||
|
||||
例如: 1、在命令行输入: crontab -e 然后添加相应的任务,wq存盘退出。
|
||||
2、直接编辑/etc/crontab 文件,即vi /etc/crontab,添加相应的任务
|
||||
11 2 21 10 * rm -rf /mnt/fb
|
||||
194
Zim/Utils/curl网站开发指南.txt
Normal file
@@ -0,0 +1,194 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-10-29T12:36:07+08:00
|
||||
|
||||
====== curl网站开发指南 ======
|
||||
Created Saturday 29 October 2011
|
||||
|
||||
http://www.ruanyifeng.com/blog/2011/09/curl.html
|
||||
|
||||
我一向以为,curl只是一个编程用的函数库。
|
||||
|
||||
最近才发现,这个命令本身,就是一个无比有用的网站开发工具,请看我整理的它的用法。
|
||||
|
||||
===================================
|
||||
|
||||
curl网站开发指南
|
||||
|
||||
阮一峰 整理
|
||||
|
||||
curl是一种命令行工具,作用是发出网络请求,然后得到和提取数据,显示在"标准输出"(stdout)上面。
|
||||
|
||||
它支持多种协议,下面举例讲解如何将它用于网站开发。
|
||||
|
||||
**一、查看网页源码**
|
||||
|
||||
直接在curl命令后加上网址,就可以看到网页源码。我们以网址www.sina.com为例(选择该网址,主要因为它的网页代码较短):
|
||||
|
||||
curl www.sina.com
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>301 Moved Permanently</title>
|
||||
</head><body>
|
||||
<h1>Moved Permanently</h1>
|
||||
<p>The document has moved <a href="http://www.sina.com.cn/">here</a>.</p>
|
||||
</body></html>
|
||||
|
||||
如果要把这个网页保存下来,可以使用-o参数,这就相当于使用wget命令了。
|
||||
|
||||
curl -o [文件名] www.sina.com
|
||||
|
||||
**二、自动跳转**
|
||||
|
||||
有的网址是自动跳转的。使用-L参数,curl就会跳转到新的网址。
|
||||
|
||||
curl -L www.sina.com
|
||||
|
||||
键入上面的命令,结果就自动跳转为www.sina.com.cn。
|
||||
|
||||
**三、显示头信息**
|
||||
|
||||
-i参数可以显示http response的头信息,连同网页代码一起。
|
||||
|
||||
curl -i www.sina.com
|
||||
|
||||
HTTP/1.0 301 Moved Permanently
|
||||
Date: Sat, 03 Sep 2011 23:44:10 GMT
|
||||
Server: Apache/2.0.54 (Unix)
|
||||
Location: http://www.sina.com.cn/
|
||||
Cache-Control: max-age=3600
|
||||
Expires: Sun, 04 Sep 2011 00:44:10 GMT
|
||||
Vary: Accept-Encoding
|
||||
Content-Length: 231
|
||||
Content-Type: text/html; charset=iso-8859-1
|
||||
Age: 3239
|
||||
X-Cache: HIT from sh201-9.sina.com.cn
|
||||
Connection: close
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>301 Moved Permanently</title>
|
||||
</head><body>
|
||||
<h1>Moved Permanently</h1>
|
||||
<p>The document has moved <a href="http://www.sina.com.cn/">here</a>.</p>
|
||||
</body></html>
|
||||
|
||||
__-I__参数则是只显示http response的头信息。
|
||||
|
||||
**四、显示通信过程**
|
||||
|
||||
-v参数可以显示一次http通信的整个过程,包括端口连接和http request头信息。
|
||||
|
||||
curl -v www.sina.com
|
||||
|
||||
* About to connect() to www.sina.com port 80 (#0)
|
||||
* Trying 61.172.201.195... connected
|
||||
* Connected to www.sina.com (61.172.201.195) port 80 (#0)
|
||||
> GET / HTTP/1.1
|
||||
> User-Agent: curl/7.21.3 (i686-pc-linux-gnu) libcurl/7.21.3 OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.18
|
||||
> Host: www.sina.com
|
||||
> Accept: */*
|
||||
>
|
||||
* HTTP 1.0, assume close after body
|
||||
< HTTP/1.0 301 Moved Permanently
|
||||
< Date: Sun, 04 Sep 2011 00:42:39 GMT
|
||||
< Server: Apache/2.0.54 (Unix)
|
||||
< Location: http://www.sina.com.cn/
|
||||
< Cache-Control: max-age=3600
|
||||
< Expires: Sun, 04 Sep 2011 01:42:39 GMT
|
||||
< Vary: Accept-Encoding
|
||||
< Content-Length: 231
|
||||
< Content-Type: text/html; charset=iso-8859-1
|
||||
< X-Cache: MISS from sh201-19.sina.com.cn
|
||||
< Connection: close
|
||||
<
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>301 Moved Permanently</title>
|
||||
</head><body>
|
||||
<h1>Moved Permanently</h1>
|
||||
<p>The document has moved <a href="http://www.sina.com.cn/">here</a>.</p>
|
||||
</body></html>
|
||||
* Closing connection #0
|
||||
|
||||
如果你觉得上面的信息还不够,那么下面的命令可以查看更详细的通信过程。
|
||||
|
||||
curl** --trace output.txt **www.sina.com
|
||||
|
||||
或者
|
||||
|
||||
curl **--trace-ascii **output.txt www.sina.com
|
||||
|
||||
运行后,请打开output.txt文件查看。
|
||||
|
||||
**五、发送表单信息**
|
||||
|
||||
发送表单信息有GET和POST两种方法。GET方法相对简单,只要把数据附在网址后面就行。
|
||||
|
||||
curl example.com/form.cgi?data=xxx
|
||||
|
||||
POST方法必须把数据和网址分开,curl就要用到--data参数。
|
||||
|
||||
curl --data "data=xxx" example.com/form.cgi
|
||||
|
||||
如果你的数据没有经过表单编码,还可以让curl为你编码,参数是--data-urlencode。
|
||||
|
||||
curl --data-urlencode "date=April 1" example.com/form.cgi
|
||||
|
||||
**六、文件上传**
|
||||
|
||||
假定文件上传的表单是下面这样:
|
||||
|
||||
<form method="POST" enctype='multipart/form-data' action="upload.cgi">
|
||||
<input type=file name=upload>
|
||||
<input type=submit name=press value="OK">
|
||||
</form>
|
||||
|
||||
你可以用curl这样上传文件:
|
||||
|
||||
curl --form upload=@localfilename --form press=OK [URL]
|
||||
|
||||
**七、Referer字段**
|
||||
|
||||
有时你需要在http request头信息中,提供一个referer字段,表示你是从哪里跳转过来的。
|
||||
|
||||
curl --referer http://www.example.com http://www.example.com
|
||||
|
||||
**八、User Agent字段**
|
||||
|
||||
这个字段是用来表示客户端的设备信息。服务器有时会根据这个字段,针对不同设备,返回不同格式的网页,比如手机版和桌面版。
|
||||
|
||||
iPhone4的User Agent是
|
||||
|
||||
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7
|
||||
|
||||
curl可以这样模拟:
|
||||
|
||||
curl --user-agent "[User Agent]" [URL]
|
||||
|
||||
**九、cookie**
|
||||
|
||||
使用--cookie参数,可以让curl发送cookie。
|
||||
|
||||
curl --cookie "name=xxx" www.example.com
|
||||
|
||||
至于具体的cookie的值,可以从http response头信息的Set-Cookie字段中得到。
|
||||
|
||||
**十、增加头信息**
|
||||
|
||||
有时需要在http request之中,自行增加一个头信息。--header参数就可以起到这个作用。
|
||||
|
||||
curl --header "xxx: xxxxxx" http://example.com
|
||||
|
||||
**十一、HTTP认证**
|
||||
|
||||
有些网域需要HTTP认证,这时curl需要用到--user参数。
|
||||
|
||||
curl --user name:password example.com
|
||||
|
||||
【参考资料】
|
||||
|
||||
* Using cURL to automate HTTP jobs
|
||||
|
||||
* 教你学用CURL
|
||||
43
Zim/Utils/diff&patch.txt
Normal file
@@ -0,0 +1,43 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-14T16:35:13+08:00
|
||||
|
||||
====== diff&patch ======
|
||||
Created Saturday 14 May 2011
|
||||
http://blog.csdn.net/hfyinsdu/archive/2010/12/01/6047465.aspx
|
||||
|
||||
diff patch 命令
|
||||
|
||||
diff 命令常用来比较文件、目录,也可以用来制作补丁文件。所谓“补丁文件”就是“修改后的文件”与“原始文件”的差别。
|
||||
|
||||
常用的选项如下:
|
||||
|
||||
1. -u: 表示在比较结果中输出上下文中一些相同的行,这有利于人工定位。
|
||||
2. -r: 递归比较各个子目录下的文件。
|
||||
3. -N: 将不存在的文件当作空文件。
|
||||
4. -w: 忽略空格的比较。
|
||||
5. -B: 忽略空行的比较。
|
||||
例如: 假设 linux-2.6 是目录中最原始的内核,linux-2.6-ok 目录是修改过的内核,可以用下面的命令制作补丁文件 linux.diff(两个目录放在同一个目录下,命令中原始目录在前,修改过的目录在后)。
|
||||
|
||||
view plaincopy to clipboardprint?
|
||||
|
||||
$ diff -urNwB linux-2.6 linux-2.6-ok > linux.diff
|
||||
|
||||
由于 linux-2.6 是标准的代码,可以从网上下载,当发布 linux-2.6 的修改时,只需提供补丁文件,这个文件通常比较小。
|
||||
patch 命令被用来打补丁--就是依据补丁文件修改原始文件。例如上面的例子,可以通过下面的命令将 linux.diff 应用到原始目录 linux-2.6 中。假设 linux-2.6 和 linux.diff 位于同一个目录下。
|
||||
|
||||
view plaincopy to clipboardprint?
|
||||
|
||||
$ cd linux-2.6
|
||||
$ patch -p1 < ../linux.diff
|
||||
|
||||
patch命令中最重要的选项是“-pn”:补丁文件中指明了要修改的文件的路径,“-pn”表示忽略路径中的第n个斜线之前的目录。假设,linux.diff 中有如下几行:
|
||||
|
||||
view plaincopy to clipboardprint?
|
||||
|
||||
diff -urNwB linux-2.6/drivers/rtc/s3c24x0_rtc.c linux-2.6-ok/drivers/rtc/s3c24x0_rtc.c
|
||||
--- linux-2.6/drivers/rtc/s3c24x0_rtc.c 2009-09-01 01:57:42.000000000 +0800
|
||||
+++ linux-2.6-ok/drivers/rtc/s3c24x0_rtc.c 2010-11-29 22:07:34.412018000 +0800
|
||||
|
||||
使用上述命令打补丁时,patch 命令根据 linux-2.6/drivers/rtc/s3c24x0_rtc.c 寻找源文件,“-p1”表示忽略第一个斜线之前的目录,所以要修改的源文件是当前目录下的:drivers/rtc/s3c24x0_rtc.c
|
||||
|
||||
431
Zim/Utils/diff&patch/2.txt
Normal file
@@ -0,0 +1,431 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-14T16:59:24+08:00
|
||||
|
||||
====== 2 ======
|
||||
Created Saturday 14 May 2011
|
||||
|
||||
首先介绍一下diff和patch。在这里不会把man在线文档上所有的选项都介绍一下,那样也没有必要。在99%的时间里,我们只会用到几个选项。所以必须学会这几个选项。
|
||||
|
||||
1、diff
|
||||
|
||||
--------------------
|
||||
|
||||
NAME
|
||||
|
||||
diff - find differences between two files
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
diff [options] from-file to-file
|
||||
|
||||
--------------------
|
||||
|
||||
简单的说,diff的功能就是用来比较两个文件的不同,然后记录下来,也就是所谓的diff补丁。语法格式:diff 【选项】 源文件(夹) 目的文件(夹),就是要给源文件(夹)打个补丁,使之变成目的文件(夹),术语也就是“升级”。下面介绍三个最为常用选项:
|
||||
|
||||
-r 是一个递归选项,设置了这个选项,diff会将两个不同版本源代码目录中的所有对应文件全部都进行一次比较,包括子目录文件。
|
||||
|
||||
-N 选项确保补丁文件将正确地处理已经创建或删除文件的情况。
|
||||
|
||||
-u 选项以统一格式创建补丁文件,这种格式比缺省格式更紧凑些。
|
||||
|
||||
2、patch
|
||||
|
||||
------------------
|
||||
|
||||
NAME
|
||||
|
||||
patch - apply a diff file to an original
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
patch [options] [originalfile [patchfile]]
|
||||
|
||||
but usually just
|
||||
|
||||
patch -pnum <patchfile>
|
||||
|
||||
------------------
|
||||
|
||||
简单的说,patch就是利用diff制作的补丁来实现源文件(夹)和目的文件(夹)的转换。这样说就意味着你可以有源文件(夹)――>目的文件(夹),也可以目的文件(夹)――>源文件(夹)。下面介绍几个最常用选项:
|
||||
|
||||
-p0 选项要从当前目录查找目的文件(夹)
|
||||
|
||||
-p1 选项要忽略掉第一层目录,从当前目录开始查找。
|
||||
|
||||
************************************************************
|
||||
|
||||
在这里以实例说明:
|
||||
|
||||
--- old/modules/pcitable Mon Sep 27 11:03:56 1999
|
||||
|
||||
+++ new/modules/pcitable Tue Dec 19 20:05:41 2000
|
||||
|
||||
如果使用参数-p0,那就表示从当前目录找一个叫做old的文件夹,在它下面寻找modules下的pcitable文件来执行patch操作。
|
||||
|
||||
如果使用参数-p1,那就表示忽略第一层目录(即不管old),从当前目录寻找modules的文件夹,在它下面找pcitable。这样的前提是当前目 录必须为modules所在的目录。而diff补丁文件则可以在任意位置,只要指明了diff补丁文件的路径就可以了。当然,可以用相对路径,也可以用绝 对路径。不过我一般习惯用相对路径。
|
||||
************************************************************
|
||||
|
||||
-E 选项说明如果发现了空文件,那么就删除它
|
||||
|
||||
-R 选项说明在补丁文件中的“新”文件和“旧”文件现在要调换过来了(实际上就是给新版本打补丁,让它变成老版本)
|
||||
|
||||
下面结合具体实例来分析和解决,分为两种类型:为单个文件打补丁和为文件夹内的多个文件打补丁。
|
||||
|
||||
环境:在RedHat 9.0下面以armlinux用户登陆。
|
||||
|
||||
目录树如下:
|
||||
|
||||
|-- bootloader
|
||||
|
||||
|-- debug
|
||||
|
||||
|-- images
|
||||
|
||||
|-- kernel
|
||||
|
||||
|-- program
|
||||
|
||||
|-- rootfiles
|
||||
|
||||
|-- software
|
||||
|
||||
|-- source
|
||||
|
||||
|-- sysapps
|
||||
|
||||
|-- tmp
|
||||
|
||||
`-- tools
|
||||
|
||||
下面在program文件夹下面建立patch文件夹作为实验用,然后进入patch文件夹。
|
||||
|
||||
一、为单个文件进行补丁操作
|
||||
|
||||
1、建立测试文件test0、test1
|
||||
|
||||
[armlinux@lqm patch]$ cat >>test0<<EOF
|
||||
|
||||
> 111111
|
||||
|
||||
> 111111
|
||||
|
||||
> 111111
|
||||
|
||||
> EOF
|
||||
|
||||
[armlinux@lqm patch]$ more test0
|
||||
|
||||
111111
|
||||
|
||||
111111
|
||||
|
||||
111111
|
||||
|
||||
[armlinux@lqm patch]$ cat >>test1<<EOF
|
||||
|
||||
> 222222
|
||||
|
||||
> 111111
|
||||
|
||||
> 222222
|
||||
|
||||
> 111111
|
||||
|
||||
> EOF
|
||||
|
||||
[armlinux@lqm patch]$ more test1
|
||||
|
||||
222222
|
||||
|
||||
111111
|
||||
|
||||
222222
|
||||
|
||||
111111
|
||||
|
||||
2、使用diff创建补丁test1.patch
|
||||
|
||||
[armlinux@lqm patch]$ diff -uN test0 test1 > test1.patch
|
||||
|
||||
【注:因为单个文件,所以不需要-r选项。选项顺序没有关系,即可以是-uN,也可以是-Nu。】
|
||||
|
||||
[armlinux@lqm patch]$ ls
|
||||
|
||||
test0 test1 test1.patch
|
||||
|
||||
[armlinux@lqm patch]$ more test1.patch
|
||||
|
||||
************************************************************
|
||||
|
||||
patch文件的结构
|
||||
|
||||
补丁头
|
||||
|
||||
补丁头是分别由---/+++开头的两行,用来表示要打补丁的文件。---开头表示旧文件,+++开头表示新文件。
|
||||
|
||||
一个补丁文件中的多个补丁
|
||||
|
||||
一个补丁文件中可能包含以---/+++开头的很多节,每一节用来打一个补丁。所以在一个补丁文件中可以包含好多个补丁。
|
||||
|
||||
块
|
||||
|
||||
块是补丁中要修改的地方。它通常由一部分不用修改的东西开始和结束。他们只是用来表示要修改的位置。他们通常以@@开始,结束于另一个块的开始或者一个新的补丁头。
|
||||
|
||||
块的缩进
|
||||
|
||||
块会缩进一列,而这一列是用来表示这一行是要增加还是要删除的。
|
||||
|
||||
块的第一列
|
||||
|
||||
+号表示这一行是要加上的。
|
||||
|
||||
-号表示这一行是要删除的。
|
||||
|
||||
没有加号也没有减号表示这里只是引用的而不需要修改。
|
||||
|
||||
************************************************************
|
||||
|
||||
***diff命令会在补丁文件中记录这两个文件的首次创建时间,如下***
|
||||
|
||||
--- test0 2006-08-18 09:12:01.000000000 +0800
|
||||
|
||||
+++ test1 2006-08-18 09:13:09.000000000 +0800
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
+222222
|
||||
|
||||
111111
|
||||
|
||||
-111111
|
||||
|
||||
+222222
|
||||
|
||||
111111
|
||||
|
||||
[armlinux@lqm patch]$ patch -p0 < test1.patch
|
||||
|
||||
patching file test0
|
||||
|
||||
[armlinux@lqm patch]$ ls
|
||||
|
||||
test0 test1 test1.patch
|
||||
|
||||
[armlinux@lqm patch]$ cat test0
|
||||
|
||||
222222
|
||||
|
||||
111111
|
||||
|
||||
222222
|
||||
|
||||
111111
|
||||
|
||||
3、可以去除补丁,恢复旧版本
|
||||
|
||||
[armlinux@lqm patch]$ patch -RE -p0 < test1.patch
|
||||
|
||||
patching file test0
|
||||
|
||||
[armlinux@lqm patch]$ ls
|
||||
|
||||
test0 test1 test1.patch
|
||||
|
||||
[armlinux@lqm patch]$ cat test0
|
||||
|
||||
111111
|
||||
|
||||
111111
|
||||
|
||||
111111
|
||||
|
||||
二、为多个文件进行补丁操作
|
||||
|
||||
1、创建测试文件夹
|
||||
|
||||
[armlinux@lqm patch]$ mkdir prj0
|
||||
|
||||
[armlinux@lqm patch]$ cp test0 prj0
|
||||
|
||||
[armlinux@lqm patch]$ ls
|
||||
|
||||
prj0 test0 test1 test1.patch
|
||||
|
||||
[armlinux@lqm patch]$ cd prj0/
|
||||
|
||||
[armlinux@lqm prj0]$ ls
|
||||
|
||||
test0
|
||||
|
||||
[armlinux@lqm prj0]$ cat >>prj0name<<EOF
|
||||
|
||||
> --------
|
||||
|
||||
> prj0/prj0name
|
||||
|
||||
> --------
|
||||
|
||||
> EOF
|
||||
|
||||
[armlinux@lqm prj0]$ ls
|
||||
|
||||
prj0name test0
|
||||
|
||||
[armlinux@lqm prj0]$ cat prj0name
|
||||
|
||||
--------
|
||||
|
||||
prj0/prj0name
|
||||
|
||||
--------
|
||||
|
||||
[armlinux@lqm prj0]$ cd ..
|
||||
|
||||
[armlinux@lqm patch]$ mkdir prj1
|
||||
|
||||
[armlinux@lqm patch]$ cp test1 prj1
|
||||
|
||||
[armlinux@lqm patch]$ cd prj1
|
||||
|
||||
[armlinux@lqm prj1]$ cat >>prj1name<<EOF
|
||||
|
||||
> ---------
|
||||
|
||||
> prj1/prj1name
|
||||
|
||||
> ---------
|
||||
|
||||
> EOF
|
||||
|
||||
[armlinux@lqm prj1]$ cat prj1name
|
||||
|
||||
---------
|
||||
|
||||
prj1/prj1name
|
||||
|
||||
---------
|
||||
|
||||
[armlinux@lqm prj1]$ cd ..
|
||||
|
||||
2、创建补丁
|
||||
|
||||
[armlinux@lqm patch]$ diff -uNr prj0 prj1 > prj1.patch
|
||||
|
||||
[armlinux@lqm patch]$ more prj1.patch
|
||||
|
||||
diff -uNr prj0/prj0name prj1/prj0name
|
||||
|
||||
--- prj0/prj0name 2006-08-18 09:25:11.000000000 +0800
|
||||
|
||||
+++ prj1/prj0name 1970-01-01 08:00:00.000000000 +0800
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
---------
|
||||
|
||||
-prj0/prj0name
|
||||
|
||||
---------
|
||||
|
||||
diff -uNr prj0/prj1name prj1/prj1name
|
||||
|
||||
--- prj0/prj1name 1970-01-01 08:00:00.000000000 +0800
|
||||
|
||||
+++ prj1/prj1name 2006-08-18 09:26:36.000000000 +0800
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
+---------
|
||||
|
||||
+prj1/prj1name
|
||||
|
||||
+---------
|
||||
|
||||
diff -uNr prj0/test0 prj1/test0
|
||||
|
||||
--- prj0/test0 2006-08-18 09:23:53.000000000 +0800
|
||||
|
||||
+++ prj1/test0 1970-01-01 08:00:00.000000000 +0800
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
-111111
|
||||
|
||||
-111111
|
||||
|
||||
-111111
|
||||
|
||||
diff -uNr prj0/test1 prj1/test1
|
||||
|
||||
--- prj0/test1 1970-01-01 08:00:00.000000000 +0800
|
||||
|
||||
+++ prj1/test1 2006-08-18 09:26:00.000000000 +0800
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
+222222
|
||||
|
||||
+111111
|
||||
|
||||
+222222
|
||||
|
||||
+111111
|
||||
|
||||
[armlinux@lqm patch]$ ls
|
||||
|
||||
prj0 prj1 prj1.patch test0 test1 test1.patch
|
||||
|
||||
[armlinux@lqm patch]$ cp prj1.patch ./prj0
|
||||
|
||||
[armlinux@lqm patch]$ cd prj0
|
||||
|
||||
[armlinux@lqm prj0]$ patch -p1 < prj1.patch
|
||||
|
||||
patching file prj0name
|
||||
|
||||
patching file prj1name
|
||||
|
||||
patching file test0
|
||||
|
||||
patching file test1
|
||||
|
||||
[armlinux@lqm prj0]$ ls
|
||||
|
||||
prj1name prj1.patch test1
|
||||
|
||||
[armlinux@lqm prj0]$ patch -R -p1 < prj1.patch
|
||||
|
||||
patching file prj0name
|
||||
|
||||
patching file prj1name
|
||||
|
||||
patching file test0
|
||||
|
||||
patching file test1
|
||||
|
||||
[armlinux@lqm prj0]$ ls
|
||||
|
||||
prj0name prj1.patch test0
|
||||
|
||||
-------------------
|
||||
|
||||
总结一下:
|
||||
|
||||
单个文件
|
||||
|
||||
diff –uN from-file to-file >to-file.patch
|
||||
|
||||
patch –p0 < to-file.patch
|
||||
|
||||
patch –RE –p0 < to-file.patch
|
||||
|
||||
多个文件
|
||||
|
||||
diff –uNr from-docu to-docu >to-docu.patch
|
||||
|
||||
patch –p1 < to-docu.patch
|
||||
|
||||
patch –R –p1 <to-docu.patch
|
||||
|
||||
-------------------
|
||||
65
Zim/Utils/diff&patch/3.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-14T17:04:45+08:00
|
||||
|
||||
====== 3 ======
|
||||
Created Saturday 14 May 2011
|
||||
|
||||
diff和patch使用指南
|
||||
(转自:http://blog.chinaunix.net/u/24474/showart_217098.html)
|
||||
|
||||
diff和patch是一对工具,在数学上来说,diff是对两个集合的差运算,patch是对两个集合的和运算。
|
||||
diff比较两个文件或文件集合的差异,并记录下来,生成一个diff文件,这也是我们常说的patch文件,即补丁文件。
|
||||
patch能将diff文件运用于 原来的两个集合之一,从而得到另一个集合。举个例子来说文件A和文件B,经过diff之后生成了补丁文件C,那么着个过程相当于 A -B = C ,那么patch的过程就是B+C = A 或A-C =B。
|
||||
因此我们只要能得到A, B, C三个文件中的任何两个,就能用diff和patch这对工具生成另外一个文件。
|
||||
|
||||
这就是diff和patch的妙处。下面分别介绍一下两个工具的用法:
|
||||
|
||||
1. diff的用法
|
||||
|
||||
diff后面可以接两个文件名或两个目录名。 如果是一个目录名加一个文件名,那么只作用在那么个目录下的同名文件。
|
||||
|
||||
如果是两个目录的话,作用于该目录下的所有文件,不递归。如果我们希望递归执行,需要使用-r参数。
|
||||
|
||||
命令diff A B > C ,一般A是原始文件,B是修改后的文件,C称为A的补丁文件。
|
||||
不加任何参数生成的diff文件格式是一种简单的格式,这种格式只标出了不一样的行数和内容。我们需要一种更详细的格式,可以标识出不同之处的上下文环境,这样更有利于提高patch命令的识别能力。这个时候可以用-c开关。
|
||||
|
||||
|
||||
2. patch的用法
|
||||
|
||||
patch用于根据原文件和补丁文件生成目标文件。还是拿上个例子来说
|
||||
|
||||
patch A C 就能得到B, 这一步叫做对A打上了B的名字为C的补丁。
|
||||
|
||||
之一步之后,你的文件A就变成了文件B。如果你打完补丁之后想恢复到A怎么办呢?
|
||||
|
||||
patch -R B C 就可以重新还原到A了。
|
||||
|
||||
所以不用担心会失去A的问题。
|
||||
|
||||
其实patch在具体使用的时候是不用指定原文件的,因为补丁文件中都已经记载了原文件的路径和名称。patch足够聪明可以认出来。但是有时候会有点小问题。比如一般对两个目录diff的时候可能已经包含了原目录的名字,但是我们打补丁的时候会进入到目录中再使用patch,着个时候就需要你告诉 patch命令怎么处理补丁文件中的路径。可以利用-pn开关,告诉patch命令忽略的路径分隔符的个数。举例如下:
|
||||
|
||||
A文件在 DIR_A下,修改后的B文件在DIR_B下,一般DIR_A和DIR_B在同一级目录。我们为了对整个目录下的所有文件一次性diff,我们一般会到DIR_A和DIR_B的父目录下执行以下命令
|
||||
|
||||
diff -rc DIR_A DIR_B > C
|
||||
|
||||
这个时候补丁文件C中会记录了原始文件的路径为 DIR_A/A
|
||||
|
||||
现在另一个用户得到了A文件和C文件,其中A文件所在的目录也是DIR_A。 一般,他会比较喜欢在DIR_A目录下面进行patch操作,它会执行
|
||||
|
||||
patch < C
|
||||
|
||||
但是这个时候patch分析C文件中的记录,认为原始文件是./DIR_A/A,但实际上是./A,此时patch会找不到原始文件。为了避免这种情况我们可以使用-p1参数如下
|
||||
|
||||
patch -p1 < C
|
||||
|
||||
此时,patch会忽略掉第1个”/”之前的内容,认为原始文件是 ./A,这样就正确了。
|
||||
使用patch
|
||||
|
||||
patch附带有一个很好的帮助,其中罗列了很多选项,但是99%的时间只要两个选项就能满足我们的需要:
|
||||
|
||||
patch -p1 < [patchfile]
|
||||
|
||||
patch -R < [patchfile] (used to undo a patch)
|
||||
|
||||
-p1选项代表patchfile中 文件名左边目录的层数,顶层目录在不同的机器上有所不同。要使用这个选项,就要把你的patch放在要被打补丁的目录下,然后在这个目录中运行path -p1 < [patchfile]。
|
||||
71
Zim/Utils/diff&patch/4.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-14T17:06:09+08:00
|
||||
|
||||
====== 4 ======
|
||||
Created Saturday 14 May 2011
|
||||
|
||||
patch 命令用于打补丁,补丁文件是使用diff产生的
|
||||
|
||||
|
||||
patch 命令语法
|
||||
|
||||
patch [ -b [ -B Prefix ] ] [ -f ] [ -l ] [ -N ] [ -R ] [ -s ] [ -v ] [ -c | -e | -n ] [ -d Directory ] [ -D Define ] [ -F Number ] [ -i PatchFile ] [ -o OutFile ] [ -p Number ] [ -r RejectFile ] [ -x Number ] [ File ]
|
||||
|
||||
patch 命令失败或拒绝接受补丁时,会产生一个和原文件同名,以".rej"为后缀的差异文件。
|
||||
当知道 -b 时,会产生一个和原文件同名,以".orig"为后缀的备份文件。
|
||||
|
||||
常使用的 patch 参数:
|
||||
|
||||
-p 指定目录级别(从路径全称中除去几层目录)
|
||||
|
||||
如,如果补丁文件包含路径名称 /curds/whey/src/blurfl/blurfl.c,那么:
|
||||
|
||||
-p 0 使用完整路径名
|
||||
-p 1 除去前导斜杠,留下 curds/whey/src/blurfl/blurfl.c。
|
||||
-p 4 除去前导斜杠和前三个目录,留下 blurfl/blurfl.c。
|
||||
|
||||
|
||||
-d Directory 打补丁前,更改当前目录到指定目录
|
||||
|
||||
-i PatchFile 从指定文件,而不是从标准输入中读取补丁信息
|
||||
|
||||
-R 逆向补丁,这个选项在防止打错补丁很有用处
|
||||
|
||||
|
||||
补丁的产生一般用
|
||||
|
||||
diff -Nrua a b > c.patch
|
||||
|
||||
如:
|
||||
|
||||
#diff -Nrua linux-2.6.14/Makefile linux-2.6.26/Makefile >c.patch
|
||||
#cat c.patch
|
||||
|
||||
--- linux-2.6.14/Makefile 2008-07-30 16:54:20.000000000 +0800
|
||||
+++ linux-2.6.26/Makefile 2008-07-14 05:51:29.000000000 +0800
|
||||
@@ -1,8 +1,8 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
-SUBLEVEL = 14
|
||||
+SUBLEVEL = 26
|
||||
EXTRAVERSION =
|
||||
-NAME=Affluent Albatross
|
||||
+NAME = Rotary Wombat
|
||||
|
||||
# *DOCUMENTATION*
|
||||
# To see a list of typical targets execute "make help"
|
||||
|
||||
|
||||
|
||||
--- 的文件表示将被打补丁的文件 如:linux-2.6.14/Makefile
|
||||
+++ 的文件表示补丁来源文件 如:linux-2.6.26/Makefile
|
||||
|
||||
|
||||
应用 patch
|
||||
#ls
|
||||
c.patch linux-2.6.14 linux-2.6.26
|
||||
#cd linux-2.6.14
|
||||
#patch -p1 <../c.patch
|
||||
|
||||
如果有多个补丁要打,则应该注意打补丁的顺序!
|
||||
64
Zim/Utils/dumpe2fs.txt
Normal file
@@ -0,0 +1,64 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-03-27T19:14:14+08:00
|
||||
|
||||
====== dumpe2fs ======
|
||||
Created Sunday 27 March 2011
|
||||
|
||||
dumpe2fs — a command utility to dump e2fs information
|
||||
|
||||
geekard@geekard-laptop:~$ sudo dumpe2fs -h /dev/sda3
|
||||
[sudo] password for geekard:
|
||||
dumpe2fs 1.41.11 (14-Mar-2010)
|
||||
Filesystem volume name: /
|
||||
Last mounted on: /
|
||||
Filesystem UUID: 18d7325c-ab28-4fca-95a9-a5b43cc0f839
|
||||
Filesystem magic number: 0xEF53
|
||||
Filesystem revision #: 1 (dynamic)
|
||||
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
|
||||
Filesystem flags: signed_directory_hash
|
||||
Default mount options: (none)
|
||||
Filesystem state: clean
|
||||
Errors behavior: Continue
|
||||
Filesystem OS type: Linux
|
||||
Inode count: 2138112
|
||||
Block count: 8550912
|
||||
Reserved block count: 427545
|
||||
Free blocks: 7477473
|
||||
Free inodes: 1972548
|
||||
First block: 0
|
||||
Block size: 4096
|
||||
Fragment size: 4096
|
||||
Reserved GDT blocks: 1021
|
||||
Blocks per group: 32768
|
||||
Fragments per group: 32768
|
||||
Inodes per group: 8192
|
||||
Inode blocks per group: 512
|
||||
Flex block group size: 16
|
||||
Filesystem created: Sun May 30 01:01:43 2010
|
||||
Last mount time: Fri Aug 6 08:25:46 2010
|
||||
Last write time: Thu Aug 5 08:57:04 2010
|
||||
Mount count: 24
|
||||
Maximum mount count: 33
|
||||
Last checked: Fri Jul 30 11:16:00 2010
|
||||
Check interval: 15552000 (6 months)
|
||||
Next check after: Wed Jan 26 11:16:00 2011
|
||||
Lifetime writes: 19 GB
|
||||
Reserved blocks uid: 0 (user root)
|
||||
Reserved blocks gid: 0 (group root)
|
||||
First inode: 11
|
||||
Inode size: 256
|
||||
Required extra isize: 28
|
||||
Desired extra isize: 28
|
||||
Journal inode: 8
|
||||
First orphan inode: 1180043
|
||||
Default directory hash: half_md4
|
||||
Directory Hash Seed: 9f264420-8964-458c-99f1-5817fba0fd30
|
||||
Journal backup: inode blocks
|
||||
Journal features: journal_incompat_revoke
|
||||
Journal size: 128M
|
||||
Journal length: 32768
|
||||
Journal sequence: 0x00026084
|
||||
Journal start: 1
|
||||
|
||||
geekard@geekard-laptop:~$
|
||||
84
Zim/Utils/ed.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-07T15:50:46+08:00
|
||||
|
||||
====== ed ======
|
||||
Created Thursday 07 April 2011
|
||||
|
||||
ed是unix系统的标准编辑器,最初由Ken Thompson 编写,起源与qed。
|
||||
ed为匹配模式提供了正则表达式,基于ed的正则表达式渗透到了整个UNIX系统:grep和sed使用的正则表达式几乎与ed相同
|
||||
egrep,awk,ex扩展了ed的正则表达式;shell的文件名匹配语法虽然与正则表达式不同,但基本思想是相同的。
|
||||
ed提供命令来操纵连续的行和与模式匹配的行,并在这些行上进行修改。
|
||||
每个ed命令都是但字符,多数命令前面可以加一到两个行号,否则使用缺省的行号。行号的说明可以用其在文件中的绝对位置指定,
|
||||
其他特殊的行号有:$代表最后一行,.表示当前行,或采用正则表达式搜索到的下一行,以及所有这些行号的组合。
|
||||
行号可以与+-符号组合起来使用,当单独使用+-时是相对与当前行的。
|
||||
用**单独的逗号**表示行号行时,其含义是整个文档。
|
||||
ed能记住上次使用的模式,所以可以用//或??来重复搜索,且模式搜索都会回绕。
|
||||
ed记录了最后操作所在的行:如最后显示的行,添加文本或修改文本或读一个文件后新内容的最后一行,这一行用.标记,成为当前行。
|
||||
每个命令都可以对.有一个定义,通常是将其设置为该命令影响的最后一行。
|
||||
替换命令s用于将某个字符串替换为另一个字符串,除非跟着命令g,否着只有行中最左边出现的模式被替换。s命令本身并不显示被修改的行,
|
||||
除非在后面使用p,事实上大多数的ed命令都实在默默的工作,但几乎任何命令后都可以用p显示命令影响后行的结果。
|
||||
可以用u命令取消最进的替换,但.必须设置为被替换的行。
|
||||
当在ed中的某些字符出现在一个搜索模式或s命令的左边时,也具有特殊含义,这些字符被称为元字符,而使用它们的模式被称为正则表达式。
|
||||
包含*的正则表达式匹配最左边最长的串。
|
||||
全局命令g和v适合有正则表达式选择的多行的一个或多个其它命令,g命令最常用于多行的显示,替换或删除。
|
||||
m.ng/regrep/command
|
||||
m,nv/regrep/commands
|
||||
gv命令前可以冠以行号来限定范围,缺省为1,$
|
||||
|
||||
g/.../命令 对所有匹配正则表达式的行执行命令。
|
||||
m,n m d 把第m行到n行的内容移到地d行之后
|
||||
m,n t d
|
||||
用于移动和复制的命令的m、d命令的目标行不能落在m~n-1之内,如果没有指定源文本行,这默认使用当前行。
|
||||
命令=显示最后一行的行号, .= 显示当前行号,显示后当前行不改变。
|
||||
k命令用于标记行,标记适合用于文本的大块移动。
|
||||
行可以通过j命令连接起来(没有附加的空格)。
|
||||
nr filename 读文件,并将其添加到行n后,把当前行设置为读取 内容的最后一行
|
||||
m,nw filename 把行m到n的内容写到文件中,不改变当前行
|
||||
m,n W filename 。。。。。添加到。。。。。
|
||||
w,W命令的缺省范围是整个文件,r是最后一行。
|
||||
ed记得使用的第一个文件名,该名可以用命令行中取得,或者用r或w命令取得,命令f显示或改变被记住的文件名。
|
||||
f 显示被记住的文件名
|
||||
f filename 设置被记住的文件名。
|
||||
命令e用记住的文件或新的文件来重新设置ed
|
||||
e 开始重新编辑被记住的文件
|
||||
e filename 开始编辑文件
|
||||
e命令的保护方式同q命令,如果缓冲区没有被保存,第一次e将引起一个错误信息。
|
||||
|
||||
命令一览表
|
||||
|
||||
命令 含义
|
||||
.a 增加文本,自导一个只包含.的行为止
|
||||
.,.c 改变行,新文本的结束方式同a
|
||||
.,.d 删除行
|
||||
e filename 用文件重新初始化ed,若filename省略则ed用记住的文件名初始化
|
||||
f filename 设置记忆文件
|
||||
1,$g/正则表达式/命令 对每个匹配正则表达式的行执行命令
|
||||
.i 在行前插入文本,结束方式同a
|
||||
.,.+1j 把多行连成一行
|
||||
.kc 用字母c设置行biaoji
|
||||
.,.l 显示行,把不可见字符标记为可见
|
||||
.,.m 行号 把当前行移到指定行后
|
||||
.,.p 显示行
|
||||
P 在以后的命令模式下显示提示符星号
|
||||
q 退出,若缓冲区为修改则给出?提示,再一次q时立即退出,Q 为不保存改变而退出,
|
||||
$r filename 读文件
|
||||
.,.s/正则表达式/新表达式字符串/ 把任何与正则表达式匹配的内容替换为新表达式
|
||||
.,.t 行号 把当前行复制到指定的行后
|
||||
.u 取消行中的上一次改变
|
||||
1,$v/正则表达式/命令 在每个不语正则表达式匹配的行上执行命令
|
||||
1,$w filename 把所有行写到文件中,W为添加到文件末尾
|
||||
x 进入加密模式
|
||||
!command-line 执行命令,而不退出ed
|
||||
(.+1) 回车 显示下一行内容
|
||||
n 显示绝对行号的内容,n=0,1,2...
|
||||
. 当前行行号,或显示当前行的内容
|
||||
$ 最后一行行号或显示最后一行内容
|
||||
/正则表达式/ 与正则表达式匹配的下一行,当在$时回绕的奥第一行开始
|
||||
?正则表达式? 与上相反
|
||||
`c 跳到标记为c的行
|
||||
n1+n2 跳到n1+n2的行
|
||||
N1,N2 行N1到N2
|
||||
N1;N2 把当前行设为N1,然后跳到N2
|
||||
|
||||
|
||||
621
Zim/Utils/ed/ed_manual.txt
Normal file
@@ -0,0 +1,621 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-11-23T22:00:56+08:00
|
||||
|
||||
====== ed manual ======
|
||||
Created Wednesday 23 November 2011
|
||||
|
||||
===== GNU `ed' Manual =====
|
||||
|
||||
|
||||
This manual is for GNU ed (version 1.5, 30 August 2010).
|
||||
|
||||
GNU ed is a** line-oriented** text editor. It is used to create, display, modify and otherwise manipulate text files, both interactively and via shell scripts. A restricted version of ed, **red**, can only edit files in the current directory and cannot execute shell commands. Ed is the "standard" text editor in the sense that it is the original editor for Unix, and thus widely available. For most purposes, however, it is superseded by full-screen editors such as GNU Emacs or GNU Moe.
|
||||
|
||||
Overview: Overview of the ed command
|
||||
Introduction to Line Editing: Getting started with GNU ed
|
||||
Invoking Ed: Command line interface
|
||||
Line Addressing: Specifying lines/ranges in the buffer
|
||||
Regular Expressions: Patterns for selecting text
|
||||
Commands: Commands recognized by GNU ed
|
||||
Limitations: Intrinsic limits of GNU ed
|
||||
Diagnostics: GNU ed error handling
|
||||
Problems: Reporting bugs
|
||||
GNU Free Documentation License: How you can copy and share this manual
|
||||
|
||||
Copyright © 1993, 1994, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
===== 1 Overview =====
|
||||
|
||||
ed is a line-oriented text editor. It is used to create, display, modify and otherwise manipulate text files. red is a restricted ed: it can only edit files in the current directory and cannot execute shell commands.
|
||||
|
||||
If invoked with a file argument, then __a copy of file__ is read into the editor's buffer. Changes are made to this copy and not directly to file itself. Upon quitting ed, any changes not explicitly saved with a __`w' command__ are lost.
|
||||
|
||||
Editing is done in two distinct modes: **command and input**. When first invoked, ed is in command mode. In this mode commands are read from the standard input and executed to manipulate the contents of the editor buffer. A typical command might look like:
|
||||
|
||||
,s/old/new/g
|
||||
|
||||
which replaces all occurences of the string old with new.
|
||||
|
||||
When an input command, such as `a' (append), `i' (insert) or `c' (change), is given, ed enters input mode. This is the primary means of adding text to a file. In this mode, __no__ commands are available; instead, the standard input is written directly to the editor buffer. A line consists of the text up to and including a** <newline>** character. Input mode is terminated by entering a single period__ (`.') on a line__.
|
||||
|
||||
All ed commands operate on **whole lines or ranges of lines**; e.g., the `d' command deletes lines; the `m' command moves lines, and so on. It is possible to modify only a portion of a line by means of replacement, as in the example above. However even here, the `s' command is applied to whole lines at a time.
|
||||
|
||||
In general, ed commands consist of zero or more line addresses, followed by a single character command and possibly additional parameters; i.e., commands have the structure:
|
||||
|
||||
// [address [,address]]command[parameters]//
|
||||
|
||||
The addresses indicate the line or range of lines to be affected by the command. If fewer addresses are given than the command accepts, then __default addresses__ are supplied.
|
||||
|
||||
|
||||
===== 2 Introduction to Line Editing =====
|
||||
|
||||
ed was created, along with the Unix operating system, by Ken Thompson and Dennis Ritchie. It is the refinement of its more complex, programmable predecessor, QED, to which Thompson and Ritchie had already added pattern matching capabilities (see Regular Expressions).
|
||||
|
||||
For the purposes of this tutorial, a working knowledge of the Unix shell sh (see Bash) and the Unix file system is recommended, since ed is designed to interact closely with them.
|
||||
|
||||
The principal difference between line editors and display editors is that display editors provide__ instant feedback __to user commands, whereas line editors require sometimes lengthy input before any effects are seen. The advantage of instant feedback, of course, is that if a mistake is made, it can be corrected immediately, before more damage is done. Editing in ed requires more strategy and forethought; but if you are up to the task, it can be quite efficient.
|
||||
|
||||
Much of the ed command syntax is shared with other Unix utilities.
|
||||
|
||||
As with the shell, <RETURN> (the carriage-return key) enters a line of input. So when we speak of “entering” a command or some text in ed, <RETURN> is implied at the end of each line. Prior to typing <RETURN>, corrections to the line may be made by typing either <BACKSPACE> (sometimes labeled <DELETE> or <DEL>) to erase characters backwards, or **<CONTROL>-u **(i.e., hold the CONTROL key and type u) to erase the whole line.
|
||||
|
||||
When ed first opens, it expects to be told what to do but doesn't prompt us like the shell. So let's begin by telling ed to do so with the__ <P> (prompt)__ command:
|
||||
|
||||
$ ed
|
||||
P
|
||||
*
|
||||
|
||||
By default, ed uses asterisk (`*') as command prompt to avoid confusion with the shell command prompt (`$').
|
||||
|
||||
We can run Unix shell (sh) commands from inside ed by prefixing them with__ <!>__ (exclamation mark, aka “bang”). For example:
|
||||
|
||||
*!date
|
||||
Mon Jun 26 10:08:41 PDT 2006
|
||||
!
|
||||
*!for s in hello world; do echo $s; done
|
||||
hello
|
||||
world
|
||||
!
|
||||
*
|
||||
|
||||
So far, this is no different from running commands in the Unix shell. But let's say we want to edit the output of a command, or save it to a file. First we must capture the command output to a temporary location called a buffer where ed can access it. This is done with ed's <r> command (mnemonic: read):
|
||||
|
||||
*__r !cal__
|
||||
143
|
||||
*
|
||||
|
||||
Here ed is telling us that it has just read 143 characters into the editor buffer - i.e., the output of the cal command, which prints a simple ASCII calendar. To display the buffer contents we issue the __<p>__ (print) command (not to be confused with the prompt command, which is uppercase!). To indicate the range of lines in the buffer that should be printed, we prefix the command with __<,>__ (comma) which is shorthand for “**the whole buffer**”:
|
||||
|
||||
*__,p__
|
||||
September 2006
|
||||
Mo Tu We Th Fr Sa Su
|
||||
1 2 3
|
||||
4 5 6 7 8 9 10
|
||||
11 12 13 14 15 16 17
|
||||
18 19 20 21 22 23 24
|
||||
25 26 27 28 29 30
|
||||
|
||||
*
|
||||
|
||||
Now let's write the buffer contents to a file named junk with the __<w>__ (write) command. Again, we use the <,> prefix to indicate that it's the whole buffer we want:
|
||||
|
||||
*,w junk
|
||||
143
|
||||
*
|
||||
|
||||
Need we say? It's good practice to frequently write the buffer contents, since unwritten changes to the buffer will be lost when we exit ed.
|
||||
|
||||
The sample sessions below illustrate some basic concepts of line editing with ed. We begin by creating a file, `sonnet', with some help from Shakespeare. As with the shell, all input to ed must be followed by a <newline> character. Comments begin with a __`#'__.
|
||||
|
||||
$ ed
|
||||
# The `a' command is for appending text to the editor buffer.
|
||||
__ a__
|
||||
No more be grieved at that which thou hast done.
|
||||
Roses have thorns, and filvers foutians mud.
|
||||
Clouds and eclipses stain both moon and sun,
|
||||
And loathsome canker lives in sweetest bud.
|
||||
__ .__
|
||||
# Entering a single period on a line returns ed to command mode.
|
||||
# Now write the buffer to the file `sonnet' and quit:
|
||||
__ w sonnet__
|
||||
183
|
||||
# ed reports the number of characters written.
|
||||
__ q__
|
||||
$ ls -l
|
||||
total 2
|
||||
-rw-rw-r-- 1 alm 183 Nov 10 01:16 sonnet
|
||||
$
|
||||
|
||||
In the next example, some typos are corrected in the file `sonnet'.
|
||||
|
||||
$ ed sonnet
|
||||
183
|
||||
# Begin by printing the buffer to the terminal with the `p' command.
|
||||
__# The `,' means ``all lines.''__
|
||||
,p
|
||||
No more be grieved at that which thou hast done.
|
||||
Roses have thorns, and filvers foutians mud.
|
||||
Clouds and eclipses stain both moon and sun,
|
||||
And loathsome canker lives in sweetest bud.
|
||||
# Select line 2 for editing,注意, 通过输入行号可以选中并显示该行内容,同时**当前行**被定义到选中的行。
|
||||
__ 2 __
|
||||
Roses have thorns, and filvers foutians mud.
|
||||
# Use the substitute command, __`s'__, to replace `filvers' with `silver',
|
||||
# and print the result.
|
||||
__ s/filvers/silver/p__
|
||||
Roses have thorns, and silver foutians mud.
|
||||
# And correct the spelling of `fountains'.
|
||||
__ s/utia/untai/p__
|
||||
Roses have thorns, and silver fountains mud.
|
||||
__ w sonnet__
|
||||
183
|
||||
q
|
||||
$
|
||||
|
||||
Since ed is line-oriented, we have to tell it which line, or range of lines we want to edit. In the above example, we do this by specifying the line's number, or sequence in the buffer. Alternatively, we could have specified a unique string in the line, e.g., __`/filvers/'__, where the `/'s delimit the string in question. **Subsequent commands **affect only the selected line, a.k.a. the current line. Portions of that line are then replaced with the substitute command, whose syntax is `s/old/new/'.
|
||||
|
||||
Although ed accepts__ only one command per line__, the print command __`p' is an exception__, and may be appended to the end of most commands.
|
||||
|
||||
In the next example, a title is added to our sonnet.
|
||||
|
||||
$ ed sonnet
|
||||
183
|
||||
__a #把最后一行当作当前行,同时在当前行后添加内容。__
|
||||
Sonnet #50
|
||||
.
|
||||
,p
|
||||
No more be grieved at that which thou hast done.
|
||||
Roses have thorns, and silver fountains mud.
|
||||
Clouds and eclipses stain both moon and sun,
|
||||
And loathsome canker lives in sweetest bud.
|
||||
Sonnet #50
|
||||
# The title got appended to the end; we should have used `0a'
|
||||
# to append ``before the first line.''
|
||||
# Move the title to its proper place.
|
||||
__5m0p__
|
||||
Sonnet #50
|
||||
# The title is now the first line, and the current line has been
|
||||
# set to this line as well.
|
||||
,p
|
||||
Sonnet #50
|
||||
No more be grieved at that which thou hast done.
|
||||
Roses have thorns, and silver fountains mud.
|
||||
Clouds and eclipses stain both moon and sun,
|
||||
And loathsome canker lives in sweetest bud.
|
||||
__wq sonnet__
|
||||
195
|
||||
$
|
||||
|
||||
When ed opens a file, the__ current line is initially set to the last line__ of that file. Similarly, the move command `m' sets the current line to the last line moved.
|
||||
|
||||
===== 3 Invoking Ed =====
|
||||
|
||||
The format for running ed is:
|
||||
|
||||
ed [options] [file]
|
||||
red [options] [file]
|
||||
|
||||
file specifies the name of a file to read. If file is prefixed with a __bang (!)__, then it is interpreted **as a shell command**. In this case, what is read is the standard output of file executed via sh (1). To read a file whose name begins with a bang, prefix the name with a backslash (\). The default filename is set to file only if it is not prefixed with a bang.
|
||||
|
||||
ed supports the following options:
|
||||
|
||||
--help
|
||||
-h
|
||||
Print an informative help message describing the options and exit.
|
||||
--version
|
||||
-V
|
||||
Print the version number of ed on the standard output and exit.
|
||||
--loose-exit-status
|
||||
-l
|
||||
Do not exit with bad status if a command happens to "fail" (for example if a substitution command finds nothing to replace). This can be useful when ed is invoked as the editor for crontab.
|
||||
--prompt=string
|
||||
-p string
|
||||
Specifies a __command prompt__. This may be toggled on and off with the `P' command.
|
||||
--restricted
|
||||
-r
|
||||
Run in restricted mode. This mode disables edition of files out of the current directory and execution of shell commands.
|
||||
--quiet
|
||||
--silent
|
||||
-s
|
||||
Suppresses diagnostics. This should be used if ed's standard input is from a script.
|
||||
--traditional
|
||||
-G
|
||||
Forces backwards compatibility. This affects the behavior of the ed commands `G', `V', `f', `l', `m', `t' and `!!'. If the default behavior of these commands does not seem familiar, then try invoking ed with this switch.
|
||||
--verbose
|
||||
-v
|
||||
Verbose mode. This may be toggled on and off with the `H' command.
|
||||
|
||||
|
||||
===== 4 Line Addressing =====
|
||||
|
||||
**An address represents the number of a line** in the buffer. ed maintains a__ current address__ which is typically supplied to commands as the default address when none is specified. When a file is first read, the current address is set to the __last line__ of the file. In general, the current address is set to the last line affected by a command.
|
||||
|
||||
A line address is constructed from one of the bases in the list below, optionally followed by a __numeric offset__. The offset may include any combination of digits, operators (i.e., `+' and `-') and whitespace. Addresses are read from left to right, and their values may be__ absolute or relative__ to the current address.
|
||||
|
||||
One exception to the rule that addresses represent line numbers is the __address `0'__ (zero). This means “before the first line,” and is valid wherever it makes sense.
|
||||
|
||||
An __address range i__s two addresses separated either by a comma or semicolon. The value of the first address in a range **cannot exceed **the value of the second. If only one address is given in a range, then the __second address __is set to the given address. If an n-tuple of addresses is given where n > 2, then the corresponding range is determined by the __last two addresses __in the n-tuple. If only one address is expected, then the __last address __is used.
|
||||
|
||||
Each address in a **comma-delimited(逗号分割)**range is interpreted relative to the current address. In a__ semicolon-delimited__ (分号分割)range, the first address is used to set the current address, and the second address is interpreted relative to the first.
|
||||
|
||||
The following address symbols are recognized.
|
||||
|
||||
.
|
||||
The current line (address) in the buffer.
|
||||
$
|
||||
The last line in the buffer.
|
||||
n
|
||||
The nth, line in the buffer where n is a number in the range `0,$'.
|
||||
+
|
||||
The next line. This is equivalent to `+1' and may be repeated with cumulative effect.
|
||||
-
|
||||
The previous line. This is equivalent to `-1' and may be repeated with cumulative effect.
|
||||
+n
|
||||
whitespace n
|
||||
The nth next line, where n is a non-negative number. Whitespace followed by a number n is interpreted as `+n'.
|
||||
-n
|
||||
The nth previous line, where n is a non-negative number.
|
||||
,
|
||||
__ The first through last lines __in the buffer. This is equivalent to the address range `1,$'.
|
||||
;
|
||||
__The current through last lines__ in the buffer. This is equivalent to the address range `.,$'.
|
||||
/re/
|
||||
The **next line** containing the regular expression re. The search **wraps to** the beginning of the buffer and continues down to the current line, if necessary. __`//'__ repeats the last search.
|
||||
?re?
|
||||
The **previous **line containing the regular expression re. The search **wraps** to the end of the buffer and continues up to the current line, if necessary. __`??' __repeats the last search.
|
||||
__'x__
|
||||
The apostrophe-x character pair addresses the line previously marked by a__ `k' (mark) command__, where `x' is a lower case letter from the portable character set.
|
||||
|
||||
===== 5 Regular Expressions =====
|
||||
|
||||
Regular expressions are patterns used in selecting text. For example, the ed command
|
||||
|
||||
g/string/
|
||||
|
||||
prints all lines containing string. Regular expressions are also used by the `s' command for selecting old text to be replaced with new text.
|
||||
|
||||
In addition to a specifying string literals, regular expressions can represent classes of strings. Strings thus represented are said to be matched by the corresponding regular expression. If it is possible for a regular expression to match several strings in a line, then the left-most longest match is the one selected.
|
||||
|
||||
The following symbols are used in constructing regular expressions:
|
||||
|
||||
c
|
||||
Any character c not listed below, including `{', `}', `(', `)', `<' and `>', matches itself.
|
||||
\c
|
||||
Any backslash-escaped character c, other than `{', ``}', `(', `)', `<', `>', `b', `B', `w', `W', `+' and `?', matches itself.
|
||||
.
|
||||
Matches any single character.
|
||||
[char-class]
|
||||
Matches any single character in char-class. To include a `]' in char-class, it must be the first character. A range of characters may be specified by separating the end characters of the range with a `-', e.g., `a-z' specifies the lower case characters. The following literal expressions can also be used in char-class to specify sets of characters:
|
||||
|
||||
[:alnum:] [:cntrl:] [:lower:] [:space:]
|
||||
[:alpha:] [:digit:] [:print:] [:upper:]
|
||||
[:blank:] [:graph:] [:punct:] [:xdigit:]
|
||||
|
||||
|
||||
If `-' appears as the first or last character of char-class, then it matches itself. All other characters in char-class match themselves.
|
||||
|
||||
Patterns in char-class of the form:
|
||||
|
||||
[.col-elm.]
|
||||
[=col-elm=]
|
||||
|
||||
|
||||
where col-elm is a collating element are interpreted according to locale (5). See regex (3) for an explanation of these constructs.
|
||||
[^char-class]
|
||||
Matches any single character, other than newline, not in char-class. char-class is defined as above.
|
||||
^
|
||||
If `^' is the first character of a regular expression, then it anchors the regular expression to the beginning of a line. Otherwise, it matches itself.
|
||||
$
|
||||
If `$' is the last character of a regular expression, it anchors the regular expression to the end of a line. Otherwise, it matches itself.
|
||||
\(re\)
|
||||
Defines a (possibly null) subexpression re. Subexpressions may be nested. A subsequent backreference of the form `\n', where n is a number in the range [1,9], expands to the text matched by the nth subexpression. For example, the regular expression `\(a.c\)\1' matches the string `abcabc', but not `abcadc'. Subexpressions are ordered relative to their left delimiter.
|
||||
*
|
||||
Matches the single character regular expression or subexpression immediately preceding it zero or more times. If `*' is the first character of a regular expression or subexpression, then it matches itself. The `*' operator sometimes yields unexpected results. For example, the regular expression `b*' matches the beginning of the string `abbb', as opposed to the substring `bbb', since a null match is the only left-most match.
|
||||
\{n,m\}
|
||||
\{n,\}
|
||||
\{n\}
|
||||
Matches the single character regular expression or subexpression immediately preceding it at least n and at most m times. If m is omitted, then it matches at least n times. If the comma is also omitted, then it matches exactly n times. If any of these forms occurs first in a regular expression or subexpression, then it is interpreted literally (i.e., the regular expression `\{2\}' matches the string `{2}', and so on).
|
||||
\<
|
||||
\>
|
||||
Anchors the single character regular expression or subexpression immediately following it to the beginning (in the case of `\<') or ending (in the case of `\>') of a word, i.e., in ASCII, a maximal string of alphanumeric characters, including the underscore (_).
|
||||
|
||||
The following extended operators are preceded by a backslash `\' to distinguish them from traditional ed syntax.
|
||||
|
||||
\`
|
||||
\'
|
||||
Unconditionally matches the beginning `\`' or ending `\'' of a line.
|
||||
\?
|
||||
Optionally matches the single character regular expression or subexpression immediately preceding it. For example, the regular expression `a[bd]\?c' matches the strings `abc', `adc' and `ac'. If `\?' occurs at the beginning of a regular expressions or subexpression, then it matches a literal `?'.
|
||||
\+
|
||||
Matches the single character regular expression or subexpression immediately preceding it one or more times. So the regular expression `a+' is shorthand for `aa*'. If `\+' occurs at the beginning of a regular expression or subexpression, then it matches a literal `+'.
|
||||
\b
|
||||
Matches the beginning or ending (null string) of a word. Thus the regular expression `\bhello\b' is equivalent to `\<hello\>'. However, `\b\b' is a valid regular expression whereas `\<\>' is not.
|
||||
\B
|
||||
Matches (a null string) inside a word.
|
||||
\w
|
||||
Matches any character in a word.
|
||||
\W
|
||||
Matches any character not in a word.
|
||||
|
||||
Next: Limitations, Previous: Regular Expressions, Up: Top
|
||||
6 Commands
|
||||
|
||||
All ed commands are single characters, though some require additonal parameters. If a command's parameters extend over several lines, then each line except for the last must be terminated with a backslash (`\').
|
||||
|
||||
In general, at most one command is allowed per line. However, most commands accept a print suffix, which is any of `p' (print), `l' (list), or `n' (enumerate), to print the last line affected by the command.
|
||||
|
||||
An interrupt (typically <Control-C>) has the effect of aborting the current command and returning the editor to command mode.
|
||||
|
||||
ed recognizes the following commands. The commands are shown together with the default address or address range supplied if none is specified (in parenthesis).
|
||||
|
||||
(.)a
|
||||
Appends text to the buffer after the addressed line, which may be the address `0' (zero). Text is entered in input mode. The current address is set to last line entered.
|
||||
(.,.)c
|
||||
Changes lines in the buffer. The addressed lines are deleted from the buffer, and text is appended in their place. Text is entered in input mode. The current address is set to last line entered.
|
||||
(.,.)d
|
||||
Deletes the addressed lines from the buffer. If there is a line after the deleted range, then the current address is set to this line. Otherwise the current address is set to the line before the deleted range.
|
||||
e file
|
||||
Edits file, and sets the default filename. If file is not specified, then the default filename is used. Any lines in the buffer are deleted before the new file is read. The current address is set to the last line read.
|
||||
e !command
|
||||
Edits the standard output of `!command', (see the `!' command below). The default filename is unchanged. Any lines in the buffer are deleted before the output of command is read. The current address is set to the last line read.
|
||||
E file
|
||||
Edits file unconditionally. This is similar to the `e' command, except that unwritten changes are discarded without warning. The current address is set to the last line read.
|
||||
f file
|
||||
Sets the default filename to file. If file is not specified, then the default unescaped filename is printed.
|
||||
(1,$)g /re/command-list
|
||||
Global command. Applies command-list to each of the addressed lines matching a regular expression re. The current address is set to the line currently matched before command-list is executed. At the end of the `g' command, the current address is set to the last line affected by command-list.
|
||||
|
||||
At least the first command of command-list must appear on the same line as the `g' command. All lines of a multi-line command-list except the last line must be terminated with a backslash (`\'). Any commands are allowed, except for `g', `G', `v', and `V'. By default, a newline alone in command-list is equivalent to a `p' command. If ed is invoked with the command-line option `-G', then a newline in command-list is equivalent to a `.+1p' command.
|
||||
(1,$)G /re/
|
||||
Interactive global command. Interactively edits the addressed lines matching a regular expression re. For each matching line, the line is printed, the current address is set, and the user is prompted to enter a command-list. At the end of the `G' command, the current address is set to the last line affected by (the last) command-list.
|
||||
|
||||
The format of command-list is the same as that of the `g' command. A newline alone acts as a null command list. A single `&' repeats the last non-null command list.
|
||||
H
|
||||
Toggles the printing of error explanations. By default, explanations are not printed. It is recommended that ed scripts begin with this command to aid in debugging.
|
||||
h
|
||||
Prints an explanation of the last error.
|
||||
(.)i
|
||||
Inserts text in the buffer before the current line. The address `0' (zero) is valid for this command; it is equivalent to address `1'. Text is entered in input mode. The current address is set to the last line entered.
|
||||
(.,.+1)j
|
||||
Joins the addressed lines. The addressed lines are deleted from the buffer and replaced by a single line containing their joined text. The current address is set to the resultant line.
|
||||
(.)kx
|
||||
Marks a line with a lower case letter `x'. The line can then be addressed as `'x' (i.e., a single quote followed by `x') in subsequent commands. The mark is not cleared until the line is deleted or otherwise modified.
|
||||
(.,.)l
|
||||
Prints the addressed lines unambiguously. The end of each line is marked with a `$', and every `$' character within the text is printed with a preceding backslash. The current address is set to the last line printed.
|
||||
(.,.)m(.)
|
||||
Moves lines in the buffer. The addressed lines are moved to after the right-hand destination address, which may be the address `0' (zero). The current address is set to the new address of the last line moved.
|
||||
(.,.)n
|
||||
Prints the addressed lines, preceding each line by its line number and a <tab>. The current address is set to the last line printed.
|
||||
(.,.)p
|
||||
Prints the addressed lines. The current address is set to the last line printed.
|
||||
P
|
||||
Toggles the command prompt on and off. Unless a prompt is specified with command-line option `-p', the command prompt is by default turned off.
|
||||
q
|
||||
Quits ed.
|
||||
Q
|
||||
Quits ed unconditionally. This is similar to the q command, except that unwritten changes are discarded without warning.
|
||||
($)r file
|
||||
Reads file to after the addressed line. If file is not specified, then the default filename is used. If there is no default filename prior to the command, then the default filename is set to file. Otherwise, the default filename is unchanged. The current address is set to the last line read.
|
||||
($)r !command
|
||||
Reads to after the addressed line the standard output of `!command', (see the `!' command below). The default filename is unchanged. The current address is set to the last line read.
|
||||
(.,.)s /re/replacement/
|
||||
(.,.)s /re/replacement/g
|
||||
(.,.)s /re/replacement/n
|
||||
Replaces text in the addressed lines matching a regular expression re with replacement. By default, only the first match in each line is replaced. If the `g' (global) suffix is given, then every match is replaced. The n suffix, where n is a postive number, causes only the nth match to be replaced. It is an error if no substitutions are performed on any of the addressed lines. The current address is set to the last line affected.
|
||||
|
||||
re and replacement may be delimited by any character other than <space>, <newline> and the characters used by the form of the `s' command shown below. If one or two of the last delimiters is omitted, then the last line affected is printed as if the print suffix `p' were specified.
|
||||
|
||||
An unescaped `&' in replacement is replaced by the currently matched text. The character sequence `\m' where m is a number in the range [1,9], is replaced by the mth backreference expression of the matched text. If replacement consists of a single `%', then replacement from the last substitution is used. Newlines may be embedded in replacement if they are escaped with a backslash (`\').
|
||||
(.,.)s
|
||||
Repeats the last substitution. This form of the `s' command accepts a count suffix n, and any combination of the characters `r', `g', and `p'. If a count suffix n is given, then only the nth match is replaced. The `r' suffix causes the regular expression of the last search to be used instead of the that of the last substitution. The `g' suffix toggles the global suffix of the last substitution. The `p' suffix toggles the print suffix of the last substitution. The current address is set to the last line affected.
|
||||
(.,.)t(.)
|
||||
Copies (i.e., transfers) the addressed lines to after the right-hand destination address, which may be the address `0' (zero). The current address is set to the last line copied.
|
||||
u
|
||||
Undoes the last command and restores the current address to what it was before the command. The global commands `g', `G', `v', and `V' are treated as a single command by undo. `u' is its own inverse.
|
||||
(1,$)v /re/command-list
|
||||
This is similar to the `g' command except that it applies command-list to each of the addressed lines not matching the regular expression re.
|
||||
(1,$)V /re/
|
||||
This is similar to the `G' command except that it interactively edits the addressed lines not matching the regular expression re.
|
||||
(1,$)w file
|
||||
Writes the addressed lines to file. Any previous contents of file is lost without warning. If there is no default filename, then the default filename is set to file, otherwise it is unchanged. If no filename is specified, then the default filename is used. The current address is unchanged.
|
||||
(1,$)w !command
|
||||
Writes the addressed lines to the standard input of `!command', (see the `!' command below). The default filename and current address are unchanged.
|
||||
(1,$)wq file
|
||||
Writes the addressed lines to file, and then executes a `q' command.
|
||||
(1,$)W file
|
||||
Appends the addressed lines to the end of file. This is similar to the `w' command, expect that the previous contents of file is not clobbered. The current address is unchanged.
|
||||
(.)x
|
||||
Copies (puts) the contents of the cut buffer to after the addressed line. The current address is set to the last line copied.
|
||||
(.,.)y
|
||||
Copies (yanks) the addressed lines to the cut buffer. The cut buffer is overwritten by subsequent `y', `s', `j', `d', or `c' commands. The current address is unchanged.
|
||||
(.+1)z n
|
||||
Scrolls n lines at a time starting at addressed line. If n is not specified, then the current window size is used. The current address is set to the last line printed.
|
||||
!command
|
||||
Executes command via sh (1). If the first character of command is `!', then it is replaced by text of the previous `!command'. ed does not process command for backslash (`\') escapes. However, an unescaped `%' is replaced by the default filename. When the shell returns from execution, a `!' is printed to the standard output. The current line is unchanged.
|
||||
(.,.)#
|
||||
Begins a comment; the rest of the line, up to a newline, is ignored. If a line address followed by a semicolon is given, then the current address is set to that address. Otherwise, the current address is unchanged.
|
||||
($)=
|
||||
Prints the line number of the addressed line.
|
||||
(.+1)<newline>
|
||||
An address alone prints the addressed line. A <newline> alone is equivalent to `+1p'. the current address is set to the address of the printed line.
|
||||
|
||||
Next: Diagnostics, Previous: Commands, Up: Top
|
||||
7 Limitations
|
||||
|
||||
If the terminal hangs up, ed attempts to write the buffer to file ed.hup or, if this fails, to $HOME/ed.hup.
|
||||
|
||||
ed processes file arguments for backslash escapes, i.e., in a filename, any character preceded by a backslash (`\') is interpreted literally.
|
||||
|
||||
If a text (non-binary) file is not terminated by a newline character, then ed appends one on reading/writing it. In the case of a binary file, ed does not append a newline on reading/writing.
|
||||
|
||||
Per line overhead: 2 pointers, 1 long int, and 1 int.
|
||||
|
||||
Next: Problems, Previous: Limitations, Up: Top
|
||||
8 Diagnostics
|
||||
|
||||
When an error occurs, if ed's input is from a regular file or here document, then it exits, otherwise it prints a `?' and returns to command mode. An explanation of the last error can be printed with the `h' (help) command.
|
||||
|
||||
If the `u' (undo) command occurs in a global command list, then the command list is executed only once.
|
||||
|
||||
Attempting to quit ed or edit another file before writing a modified buffer results in an error. If the command is entered a second time, it succeeds, but any changes to the buffer are lost.
|
||||
|
||||
ed exits with 0 if no errors occurred; otherwise >0.
|
||||
|
||||
Next: GNU Free Documentation License, Previous: Diagnostics, Up: Top
|
||||
9 Reporting Bugs
|
||||
|
||||
There are probably bugs in ed. There are certainly errors and omissions in this manual. If you report them, they will get fixed. If you don't, no one will ever know about them and they will remain unfixed for all eternity, if not longer.
|
||||
|
||||
If you find a bug in ed, please send electronic mail to bug-ed@gnu.org. Include the version number, which you can find by running `ed --version'.
|
||||
|
||||
Previous: Problems, Up: Top
|
||||
10 GNU Free Documentation License
|
||||
Version 1.3, 3 November 2008
|
||||
|
||||
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
|
||||
http://fsf.org/
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
PREAMBLE
|
||||
|
||||
The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
|
||||
|
||||
This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
|
||||
|
||||
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
|
||||
APPLICABILITY AND DEFINITIONS
|
||||
|
||||
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
|
||||
|
||||
A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
|
||||
|
||||
A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
|
||||
|
||||
The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
|
||||
|
||||
The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
||||
|
||||
A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.
|
||||
|
||||
Examples of suitable formats for Transparent copies include plain ascii without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
|
||||
|
||||
The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
|
||||
|
||||
The “publisher” means any person or entity that distributes copies of the Document to the public.
|
||||
|
||||
A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.
|
||||
|
||||
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
|
||||
VERBATIM COPYING
|
||||
|
||||
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
|
||||
|
||||
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
|
||||
COPYING IN QUANTITY
|
||||
|
||||
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
|
||||
|
||||
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
|
||||
|
||||
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
|
||||
|
||||
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
|
||||
MODIFICATIONS
|
||||
|
||||
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
|
||||
Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
|
||||
List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
|
||||
State on the Title page the name of the publisher of the Modified Version, as the publisher.
|
||||
Preserve all the copyright notices of the Document.
|
||||
Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
|
||||
Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
|
||||
Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
|
||||
Include an unaltered copy of this License.
|
||||
Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
|
||||
Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
|
||||
For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
|
||||
Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
|
||||
Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
|
||||
Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
|
||||
Preserve any Warranty Disclaimers.
|
||||
|
||||
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
|
||||
|
||||
You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
|
||||
|
||||
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
|
||||
|
||||
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
|
||||
COMBINING DOCUMENTS
|
||||
|
||||
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
|
||||
|
||||
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
|
||||
|
||||
In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”
|
||||
COLLECTIONS OF DOCUMENTS
|
||||
|
||||
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
|
||||
|
||||
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
|
||||
AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
|
||||
|
||||
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
|
||||
TRANSLATION
|
||||
|
||||
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
|
||||
|
||||
If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
|
||||
TERMINATION
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.
|
||||
|
||||
However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.
|
||||
FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
|
||||
|
||||
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document.
|
||||
RELICENSING
|
||||
|
||||
“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site.
|
||||
|
||||
“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.
|
||||
|
||||
“Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.
|
||||
|
||||
An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.
|
||||
|
||||
The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.
|
||||
|
||||
ADDENDUM: How to use this License for your documents
|
||||
|
||||
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
|
||||
|
||||
Copyright (C) year your name.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
|
||||
Texts. A copy of the license is included in the section entitled ``GNU
|
||||
Free Documentation License''.
|
||||
|
||||
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with...Texts.” line with this:
|
||||
|
||||
with the Invariant Sections being list their titles, with
|
||||
the Front-Cover Texts being list, and with the Back-Cover Texts
|
||||
being list.
|
||||
|
||||
If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.
|
||||
|
||||
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
|
||||
429
Zim/Utils/emacs.txt
Normal file
@@ -0,0 +1,429 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-01T22:15:46+08:00
|
||||
|
||||
===== emacs =====
|
||||
Created Friday 01 April 2011
|
||||
|
||||
====== 生活在 Emacs 中 ======
|
||||
|
||||
http://www.ibm.com/developerworks/cn/education/linux/l-emacs/index.html
|
||||
|
||||
===== 起源概述 =====
|
||||
|
||||
在本教程中,我们将很快地讲述许多知识。首先我们要讲 Emacs 是什么和它的起源。然后,我们马上开始讲该编辑器的使用:击键、命令、Emacs 环境和您起步所需的一些基本命令。我将为您展示添加和删除文本、剪切(kill)和粘贴(yank)文本的各种方法。
|
||||
|
||||
下一步,我们将介绍 Emacs 的光标移动系统。然后将讲搜索和替换功能。接着,我将向您展示 Emacs 对文件和缓冲区的作用。在结束本教程前,我将粗略地讲述只有在 Emacs 中才能找到的高级功能和额外的特性,包括模式、代码编写、连接和游戏。
|
||||
|
||||
在学完本教程后,您将舒适地在 Emacs 环境中工作,感受到通过它您所能得到的力量。我们开始吧。
|
||||
|
||||
===== Emacs 是什么? =====
|
||||
|
||||
根据 GNU.org 的描述,**Emacs 是可扩展的、可定制的、自我编制文档实时显示的编辑器。它提供真正的 LISP ― 平滑地集成进编辑器 ― 用于编写扩展并提供 X Window 系统的一个界面。**
|
||||
|
||||
曾有人说(恐怕不是完全在开玩笑)Emacs 能很好地完成太多的不同工作,以至于它快成为**不错的操作系统** ― 就缺一个象样的文本编辑器。
|
||||
|
||||
但认真地说:**Emacs 是一个健壮的可扩展的文本编辑环境**。它在设计时被加入很多很多东西,包括编译和调试界面、电子邮件、游戏和 Eliza。特别对于那些以写作或/和写代码为生的人来说,可以很容易地在早上启动几个 Emacs 会话,开始工作,一整天不运行其它应用程序,本教程故此得名:生活在 Emacs 中。
|
||||
|
||||
===== 起源和其它选择 =====
|
||||
|
||||
最初的 Emacs 是由 Richard Stallman 在 20 世纪 70 年代为在 Massachusetts Institute for Technology 的 Incompatible Timesharing System(ITS)而写的。最早在 1984 年发布的 GNU Emacs 也是才华横溢的 Richard Stallman 的杰作。GNU Emacs 可从 GNU.org 得到,授权方式是自由软件基金会(Free Software Foundation)的 GNU GPL(请查阅参考资料找到链接)。
|
||||
|
||||
GNU Emacs 有一个主要的“竞争者”― XEmacs ― 它是 Emacs 代码库的一个分支的结果。这个分支发生在很久以前,虽然用户界面的主要部分相同或很相似,但是下层的扩展和 LISP 代码是不兼容的。然而,两者之间的移植是可能的。
|
||||
|
||||
许多 Linux 分发版有这两种版本的 Emacs,根据出版者的选择,其中一个版本的安装优先于另一个。例如在 Debian 中,如果您选择安装 Emacs,Debian 将安装 GNU Emacs,Red Hat 7.2 也是这样。上一次我安装 Caldera OpenLinux 时,它默认为 **XEmacs**.
|
||||
|
||||
===== 开始学用 Emacs =====
|
||||
|
||||
==== Emacs 击键约定 ====
|
||||
|
||||
Emacs 自身的文档有独特的方式来描述用于定义操作的击键,如下:
|
||||
|
||||
C-<chr> == Ctrl + 字符,同时按。
|
||||
M-<chr> == Meta + 字符,同时按。
|
||||
|
||||
但是,什么是 Meta?Meta 可以是一个专用键(有时这样标记),它可能是 Alt 键,它也可能在您系统所用的键映射表(keymap)中根本不存在。那没关系;Meta 有替代键,就是先按 Esc 键,再按后面的字符键(而**不是一起按**)。这样产生的结果和 M-<chr> 相同。
|
||||
|
||||
现在启动您的 Emacs(或 XEmacs)副本,让我们快点取得进展。第一步,在终端或控制台中输入 emacs practice1.text 。
|
||||
|
||||
|
||||
===== 命令和键绑定 =====
|
||||
|
||||
Emacs 实现了一个版本 LISP,一种**线程语言**,用于构建它的**命令和扩展**。**所有的命令都有名字**,例如 Buffer-menu-bury、backward-char 和 forward-paragraph。尽管它们被有逻辑地排列和命名,但是在我当前的安装中它们的数量超过 1800 个,那需要输入很多。
|
||||
|
||||
这就是为什么许多命令要**和以 Ctrl 和 Meta 键开头的键组合绑定**的原因。调用一个有名字的命令的方法是先输入 M-x,再输入命令名。得到键绑定列表的长格式命令是 M-x describe-bindings。幸运的是它有一个键绑定:**C-h b**。
|
||||
|
||||
切换到列表窗口按 C-x o,递增的搜索按 C-s,切换回您的工作窗口按__ C-x o__,关闭除当前缓冲区以外的所有窗口按 C-x 1。试一试这些命令,看一看其中的一些 ― 大约共有 600 个键绑定。不要担心我们在这次短途旅行中用到的命令,我们到时候将在本教程后半部重访所有这些命令。
|
||||
|
||||
===== 第一指示 =====
|
||||
|
||||
===== 退出 =====
|
||||
:我第一次使用 Emacs 时,我发现我迷失在文档中的某处或肯定不是由我自己打开的混乱的缓冲区中或其它什么地方。在那时,所有我所想做的就是退出系统,这样我可以重新再来,找出我在哪里错了。您可以输入以下击键序列来退出 Emacs: __C-x C-c__ 。
|
||||
|
||||
根据您在前面一屏看到的击键约定,它的意思是按 Ctrl + x,再按 Ctrl + c。如果您更改了任何打开的文件,那么 Emacs 将提示您,例如:
|
||||
|
||||
Save file /home/bilbrey/practice1.txt? (y, n, !, ., q,
|
||||
C-r or C-h)
|
||||
|
||||
如果我做了我在乎的修改,我将对这样的提示回答 y 。如果按 ! ,就直接退出了,什么也没保存。
|
||||
|
||||
Emacs 启动后,打开现有的文件的方法是按__ C-x C-f __来查找文件并把它装入缓冲区。
|
||||
|
||||
另一方面,我常常想保存我已完成的工作再继续输入。保存我的工作再继续的击键组合是__ C-x C-s__。
|
||||
|
||||
|
||||
===== Emacs 视图,第 1 部分 =====
|
||||
|
||||
所有的 Emacs 和 XEmacs 屏幕有三个主要的部分:**缓冲区、状态栏和位于底部的小缓冲区**。本教程的 XML 格式的版本出现在下图中。
|
||||
|
||||
|
||||
===== Emacs 视图,第 2 部分 =====
|
||||
|
||||
前面一屏中的抓屏来自 GNU Emacs 的可使用 X 的版本。在那张视图中与仅有文本模式的版本(例如在控制台或终端窗口中)无关的部分是上部的 GUI 按钮菜单和可使用鼠标的滚动条(在多数情况下)。
|
||||
|
||||
主要的编辑窗口可被分割成两个或更多个窗口,这些窗口可以是**同一个缓冲区(文件)的视图,也可以是不同的缓冲区的视图**。请参阅 Emacs 中的窗口这一屏获取更多信息。
|
||||
|
||||
在起初的配置中,编辑窗口的底部分界处有一个**状态栏(也被称为模式栏)**。有多个可见窗口的时候,**每个窗口有自己的状态栏**。状态栏中有缓冲区中的文本是否被更改的指示器、与名字关联的文件名、模式(显示在前面抓屏中的是 SGML)、当前的行号和用全部文本的百分比来表示的**光标位置**。模式指示的是 Emacs 所认为的它正在工作的**文本的类**型并相应地修改菜单和功能。
|
||||
|
||||
抓屏中包含 [Wrote...] 消息的底部那行被称为**小缓冲区**。它被用来**显示输入了一半的命令和命令的运行结果**,有时还显示一点点帮助。
|
||||
|
||||
===== 常用文本操作 =====
|
||||
|
||||
==== 插入文本 ====
|
||||
|
||||
从某种重要意义上说,Emacs 是很容易的。无需进入插入模式或从任何特别命令模式中退出 ― 直接输入,您就已经在插入文本了。让我们在这里重申一件事:使用“保存缓冲区”命令尽早地经常地保存您的工作:C-x C-s。
|
||||
您喜欢这样吗?这是本教程中最短最容易的一屏。现在深呼吸一次,我们将进入删除文本。
|
||||
|
||||
==== 基本的删除和撤销 ====
|
||||
|
||||
删除文本的方法有两种。在这屏中,我们将讲第一种:**字符删除**。您很可能已经习惯了单独字符的删除方式:使用 Delete 键或 Backspace 键。
|
||||
|
||||
在 Emacs 中,至少有一个击键和 Delete 等同:__C-d __删除**光标下(处)**的字符。撤销字符删除的方法是使用 __C-x u__ 命令或真正的速写,__C-___。对于多次撤销来说,后者更方便。现在练习一下这些操作从而开始您的手指在 Emacs 中的训练。
|
||||
|
||||
注意:我读过的有些文档指出 Delete 键应该向后删除(backspace 或和 ^H 等同的击键)而** C-d 替代了 Delete**。这取决于您的操作设置和终端配置。
|
||||
|
||||
删除的字符被保存在缓冲区中,只是用于撤销,您只能通过撤销删除后的所有更改来得到那些修改。用于**多字符区域**的更“高级”形式的删除被同时保存到另一个不同的结构中,我们接下来将学习它。
|
||||
|
||||
==== Emacs 剪切和粘贴,第 1 部分 ====
|
||||
|
||||
下面是您删除比较大的块时需要用的命令(它被称为“杀死”):
|
||||
|
||||
键绑定 操作(命令)
|
||||
C-d delete-char
|
||||
M-d kill-word
|
||||
C-k kill-line
|
||||
M-k kill-sentence
|
||||
|
||||
M-Delete backward-kill-word
|
||||
C-x Delete backward-kill-sentence
|
||||
|
||||
C-k 的使用有一点窍门。使用一次后,**它剪切该行的文本但不包括换行符**。那需要再按一次 C-k。剪切段落的命令也有:**kill-paragraph 和 backward-kill-paragraph**,但它们没有键绑定。
|
||||
|
||||
那么您删除的东西到哪里去了?当然在__剪切环(kill ring)__里。__多次顺序的删除(例如重复几次按 C-k)作为一块进入剪切环__,这样很有用。在下一屏中,我们将学习存取那些数据。
|
||||
|
||||
==== Emacs 剪切和粘贴,第 2 部分 ====
|
||||
|
||||
它被称作剪切环的原因是它**存储了大于一个字符**的已删除文本。还有,它能按顺序被存取,从位于最后的最新的,到编辑会话期间第一个被删除的,接着又回到最近的。所以,从拓扑结构上说,它是环。
|
||||
|
||||
输入 C-y,粘贴最近的块。重复按 C-y 粘贴出的还是那块。
|
||||
|
||||
得到更旧的“剪切”的方法是先输入 __C-y__,您将看到最近的块。然后,输入__ M-y__,一步步遍历剪切环。每一步替换前面的粘贴。现在试一下 ― 确实很有用。
|
||||
|
||||
==== 通用参数 ====
|
||||
|
||||
键绑定为 __C-u __的命令 __universal-argument__ 可被用作许多其它操作的前缀,包括我在前几屏中给您讲的许多删除命令。
|
||||
|
||||
例如,输入 C-u 3 C-k 可删除三行。
|
||||
|
||||
若没有数字参数,__universal-argument 缺省为 4 次__。
|
||||
|
||||
|
||||
==== 复习基本操作 ====
|
||||
|
||||
下面的表格是这章讨论的所有命令和它们的键绑定。看一看它们,确认您知道它们是什么。很快地练习它们,以增加对这些操作的熟悉。在练习前,通过在主窗口中输入来插入文本。
|
||||
键绑定 操作(命令)
|
||||
C-g (Esc Esc Esc) keyboard-quit 用来退出已启动的命令
|
||||
Backspace backward-delete-char
|
||||
Delete (C-d) delete-char
|
||||
C-x u (C-_) advertised-undo
|
||||
M-d kill-word
|
||||
M-Delete backward-kill-word
|
||||
M-k kill-sentence
|
||||
C-x Delete backward-kill-sentence
|
||||
C-k kill-line
|
||||
C-y yank 等同于粘贴
|
||||
M-y 遍历剪切环,必须跟 C-y
|
||||
C-u, C-u N universal-argument,在命令前加上次数前缀
|
||||
|
||||
===== Emacs 中的光标移动 =====
|
||||
|
||||
==== 移动光标 ====
|
||||
|
||||
在 GUI 环境中运行 Emacs 意味着您可以使用鼠标或方向键(例如向上和向下的箭头以及 Home 和 End 键)在文档中移动光标。然而,我将回顾 Emacs 自身的移动方式,因为这是唯一保证能用的方法,不管您是在拨号线上的终端,还是通过控制台或 SSH 连接访问一台机器,还是任何其它方法。
|
||||
|
||||
它自身的键移动方式还有其它好处,那就是使您的手总放在键盘上,在属于它们的地方,不仅为了效率,也为了人体工学。当我在 GUI 模式中使用工具时,我发现键盘和鼠标间的环境切换使我失去 10% 的效率。
|
||||
|
||||
像前面那样启动 Emacs(输入 emacs practice1.txt ),接着在呈现在您面前的初试窗口中输入几行(或复制这屏)。
|
||||
|
||||
==== 小步子 ====
|
||||
|
||||
Emacs 光标移动 ―
|
||||
|
||||
==== 字符 ====
|
||||
|
||||
Emacs 有时用字符助记符来帮助您,使您的手指学会这些命令而无需有意识的努力。只要记住 Previous(向上)、Next(向下)、Forward(向前) 和 Back(向后)。每个的第一个字母是您的移动键。
|
||||
|
||||
__C-f __使光标向前移动一个字符,而 __C-b__ 使光标向后移动一个字符。注意这**包括换行**。__C-n__ 移到下一行,而 __C-p __使光标向上移动一行。可能的话,__垂直移动保持列不变__。然而,如果下一行或上一行比当前光标所在的列短,光标将自动移到新行的末尾。如果您继续移到更长一行,光标将回到新行中的“原来”那列。
|
||||
|
||||
|
||||
Emacs 光标移动 ―
|
||||
|
||||
==== 词、行和句 ====
|
||||
|
||||
从词移到词时,Forward 和 Back 仍然指引您,但要用 Meta 键而不是 Ctrl 键。注意__词的定义是连续的字母和数字__。在词与词之间移动时,__标点符号被算作空格__。在我们学习它们时,每个命令都试用几次。__M-f__ 使光标向前移动一个词,而 __M-b__ 向后移动一个词。
|
||||
|
||||
当我们学习更多行操作时,助记符的帮助不再那么有用:“a”和“e”键分别表示头和尾。__C-a __把您带到当前行的第一列而 __C-e__ 把您带到行末。
|
||||
|
||||
在一句句移动时,我们至少仍能用同样的字符。输入 __M-a__ 把我们带回当前句子的开头(或前一句,如果光标开始时就在句首)。__M-e__ 以同样的方式相对于句末向前移动。
|
||||
|
||||
句子由标点(!?.)和回车或**两个空格**来定义。根据文本,结果并不总是真的一句句地移动,但有点象段落。
|
||||
|
||||
|
||||
===== 大步移动 =====
|
||||
|
||||
Emacs 光标移动 ―
|
||||
|
||||
==== 屏幕 ====
|
||||
|
||||
一次移动一个屏幕是很有用的操作,下面是完成它的命令。__C-v __使文本向前滚动一个屏幕而 __M-v__ 则相反。为了方便,有**两行重叠**,使您更容易记住上下文。另外,输入__ C-l__(这是小写“L”)可以移动窗口,使当前光标位置处于窗口的中央。还可以用__M-r__在窗口中移动光标
|
||||
|
||||
最后,移到缓冲区的开头和末尾的击键如下:__M-< __把您带到开头,而 __M->__ 把您带到末尾。它们确实是 < 和 >,所以您需用 Shift 键。
|
||||
|
||||
光标移动注解
|
||||
键绑定 操作(命令)
|
||||
C-f forward-char
|
||||
C-b backward-char
|
||||
C-n next-line
|
||||
C-p previous-line
|
||||
M-f forward-word
|
||||
M-b backward-word
|
||||
C-a beginning-of-line
|
||||
C-e end-of-line
|
||||
M-a backward-sentence
|
||||
M-e forward-sentence
|
||||
C-v scroll-up
|
||||
M-v scroll-down
|
||||
C-l re-center
|
||||
M-r ??
|
||||
M-{ 段首
|
||||
M-} 段尾
|
||||
|
||||
在测试文档中练习这些击键并一直用下去。我发现我必须在一段时间内**强迫自己不用光标键和鼠标**。通过把我的手指总是放在键盘的中央一行(asdf jkl;)并有意识地使用这些命令,我很快能容易地浏览每个文件的缓冲区。
|
||||
|
||||
===== 搜索和替换 =====
|
||||
|
||||
==== 递增搜索,第 1 部分 ====
|
||||
|
||||
递增搜索是 Emacs 中我喜欢的特色之一。当您开始输入时,它们马上开始匹配文本。它的好处是您常常不需要输入整个词就可以完成搜索。
|
||||
|
||||
标准的向前递增搜索是由 __C-s__ 命令启动的。从光标位置向后搜索是由__ C-r__(isearch-backward)命令来完成。有各种内部搜索命令可使用;您可以输入以下命令来得到全部描述:
|
||||
C-h d isearch-forward
|
||||
|
||||
突出显示的包括递增匹配:向前匹配用__ C-s __和向后匹配用 __C-r__。还有,当您到达您的目标时,按 __Enter 或 C-g __来终止搜索。
|
||||
|
||||
==== 递增搜索,第 2 部分 ====
|
||||
|
||||
现在试用递增搜索。把光标移到练习文档的开头,再输入 C-s。提示符出现在小缓冲区中 ― I-search:。然后,慢慢地输入您想搜索的词的字母。随着您增加每个字母,突出显示区域在您的缓冲区中行进,显示您已输入部分的第一个匹配。在下面的屏幕片段中,您可以看到**第一个匹配在紫红色中,下一个可能的匹配在淡绿色中**。
|
||||
|
||||
==== 正则表达式搜索 ====
|
||||
|
||||
正则表达式搜索也是递增的但使用正则表达式来提供更强大的搜索功能。我不准备在本教程中讲正则表达式,但您可以找到很多不错的印刷的或在线的参考资料(请参阅参考资料)。
|
||||
|
||||
启动向前正则表达式搜索的方法是输入__ ESC C-s__(也就是,Esc 键,然后 Ctrl 键加“s”键)。类似地,向后搜索的方法是使用 __ESC C-r__。
|
||||
|
||||
例如,让我们假定由于奇怪的原因我的文本中的某处有 bartok 和 footok。我想找到任一个的最接近的实例,为此我可以只用一次正则表达式搜索而不是搜索两个再记下行号等。
|
||||
|
||||
现在,我可能输入
|
||||
|
||||
ESC C-r bar\|foo
|
||||
|
||||
它先匹配上面的 bartok。然后,随着我加上表达式的“或 foo”部分,该命令从搜索点开始重新检查,发现 footok 才是真正最接近的。现在,我可以用 C-r 或 C-s 来分别向后或向前递增搜索缓冲区中的各种 foo 和 bar。
|
||||
|
||||
==== 替换文本 ====
|
||||
|
||||
Emacs 中,替换命令有两种基本类型。第一种是**无条件替换**,它基于字符串或正则表达式规范。没有缺省的键绑定(由此我不得不得出结论它并不被认为是重要的),但它的使用方法是输入__ M-X replace-string__(或 __M-x replace-regexp__)。跟在后面的是目标字符串/表达式和替换字符串。替换是无条件的并且**仅从光标位置开始**向前替换。
|
||||
|
||||
第二个命令__ query-replace __的绑定键是__ M-%__(另一个需按 Shift 的击键)。您在小缓冲区中的提示符后输入目标和替换字符串后,每个匹配按顺序被突出显示,您会收到该采取什么操作的提示。按 ? 将显示各种可能的回答的全部列表。最常见的是:“**y”表示替换并继续,“n”表示跳过并继续,“q”表示退出,还有 ! 表示无条件替换剩下的全部匹配**。
|
||||
|
||||
在练习缓冲区中试用这些命令。
|
||||
|
||||
==== 搜索和替换总结 ====
|
||||
|
||||
下面的表总结了我们已讲过的 Emacs 基本搜索和替换功能。记住,您可以得到任何命令的详细帮助,不管它有没有键绑定,方法是输入 C-h d command-name 。
|
||||
键绑定 操作(命令)
|
||||
C-s isearch-forward
|
||||
C-r isearch-backward
|
||||
<find> search-forward
|
||||
Esc C-s isearch-forward-regexp
|
||||
Esc C-r isearch-backward-regexp
|
||||
n/a replace-string
|
||||
M-% query-replace
|
||||
|
||||
===== 缓冲区和文件 =====
|
||||
|
||||
==== 查找文件 ====
|
||||
|
||||
在 Emacs 中,文件并不是在磁盘上编辑。相反,被指定文件的副本被放入缓冲区,**所有的编辑在缓冲区中进行**;写回磁盘文件是显式操作。当您要把文件装入缓冲区进行编辑时,您“查找”它。输入__ C-x C-f __后在小缓冲区中产生如下的缺省提示符:Find file: ~/。按几次 Tab 键,得到**目录列表**,这样您就可以浏览到想要的文件(如下图所示)。然后按 Enter,把该文件读入缓冲区。
|
||||
|
||||
|
||||
==== 自动保存、保存和另存为 ====
|
||||
|
||||
好消息 ― Emacs 确实包含**自动保存**选项,通过配置该选项可以把您的文件保存到指定的位置。例如,在我的配置中,本教程的自动保存文件的名字是 #Living_In_Emacs.xml#,它位于和原始文件相同的目录。其它配置有不同的命名约定和保存位置(常常是 /var/tmp)。Emacs 自动保存的__缺省值是在 30 秒空闲时间或 300 个输入事件后。__
|
||||
|
||||
在本教程的开头,我介绍了 save-buffer 命令:C-x C-s。把缓冲区内容另存为不同文件名的对应键绑定是__ C-x C-w__。路径/文件名提示符出现在小缓冲区中,可通过一对 Tab 击键把它展开为目录列表,就象查找文件。
|
||||
|
||||
注意,__使用 write-file 命令来另存后,缓冲区和新文件名相关联__。如果您习惯于保持原文件名不变的编辑器,那么将要费点功夫来适应。
|
||||
|
||||
|
||||
==== 启动时的缓冲区 ====
|
||||
|
||||
使用多个缓冲区是很容易的。然而,Emacs 本身是一个文本应用程序,所以有一组命令用于切换缓冲区和查看它们。当 Emacs 不带文件参数启动时,有两个叫__草稿(scratch__)和__消息(messages)的初始缓冲区__。为了编辑,您打开的其它**缓冲区的命名是根据包含它们内容的文件名**。
|
||||
|
||||
草稿缓冲区的命名是适当的。它被用于**临时存储和快速 Emacs LISP 宏的开发和测试**。Emacs 退出时,它没被保存,所以别把您在乎的东西留在那。消息缓冲区包含**命令和后台活动的“系统级”输出**,如下面的摘录所示。
|
||||
|
||||
Loading sgml-mode...done
|
||||
Auto-saving...done
|
||||
Wrote /home/bilbrey/Documents/IBM/LIE/Living_In_Emacs.xml
|
||||
Auto-saving...done
|
||||
|
||||
===== Emacs 中的窗口 =====
|
||||
|
||||
接下来,考虑 Emacs 中的窗口。第一步,您可以通过输入__ C-x 2 __来水平分割,从而得到当前缓冲区的两个视图(而 __C-x 3 __垂直分割它们)。这并不打开新缓冲区**,**因为那将是数据的独立副本。相反,它是**同一缓冲区的窗口**。
|
||||
|
||||
在可见窗口之间切换的键绑定是__ C-x o__,它绑定的命令是 other-window。它在可见窗口间循环。在学 Emacs 时,我常用这个命令来切入和切出帮助窗口。当我在写代码时需要经常在模块和头文件间转来转去的时候,它也很有用。
|
||||
|
||||
把您的窗口数目减为一的方法是输入__ C-x 1__,这将最大化当前包含光标的窗口并关闭其它窗口。
|
||||
|
||||
===== 使用中的缓冲区 =====
|
||||
|
||||
试验缓冲区的方法是先打开多个测试文件。然后使用命令__ C-x C-b__ 来列出所有的缓冲区。您的列表应和这相似:
|
||||
|
||||
MR Buffer Size Mode File
|
||||
-- ------ ---- ---- ----
|
||||
.* practice1.txt 490 Text ~/practice1.txt
|
||||
test2.txt 1 Text ~/test2.txt
|
||||
test1.txt 0 Text ~/test1.txt
|
||||
* *scratch* 191 Lisp Interaction
|
||||
* *Messages* 501 Fundamental
|
||||
|
||||
|
||||
MR 列反映每个缓冲区的“改过(Modified)”和“只读(Read-Only)”状态。Buffer(名)、Size 和 File 就不必解释了(分别是缓冲区、大小和文件),我们将在本教程末尾讲 modes。切换到缓冲区列表窗口(使用 C-x o),然后把光标移到您想打开的新缓冲区的那一行,再按 Enter 来选择它。缓冲区列表在窗口中被换成所选的缓冲区。如果您愿意,您可以最大化该窗口。
|
||||
|
||||
另外,**有各种与缓冲区菜单有关的命令和相应的键绑定**。通过输入 C-h d Buffer-menu- 在窗口中列出它们,然后按 Tab 键来得到命令列表。对我来说最有用的是用于退出的__“q”__。但是它并不关闭打开的窗口。您需要自己做。
|
||||
|
||||
==== 再谈缓冲区 ====
|
||||
|
||||
如果您知道您的目的缓冲区的名字(我常常是这种情况),那么缓冲区列表的使用就没必要。先在小缓冲区中输入__ C-x b__ 以得到提示符,然后输入目的缓冲区的名字 ― 或至少输入足够的多,以致于能用 Tab 键来完成。按 Enter,把那个缓冲区在当前窗口中打开。
|
||||
|
||||
关闭(kill)当前缓冲区的方法是输入 __C-x k__。出现在小缓冲区中的第一个提示符确认被关闭的缓冲区的名字。如果该缓冲区的内容没被更改过,按 Enter 来关闭该缓冲区。否则,将有第二个确认,用于丢弃更改过的缓冲区,只能回答“yes”或“no”。
|
||||
|
||||
==== 复习:文件、缓冲区和窗口 ====
|
||||
|
||||
这一章要掌握的主要概念如下。
|
||||
|
||||
文件是磁盘上的实体。
|
||||
缓冲区是文件中的数据的副本,可被 Emacs 编辑。
|
||||
**窗口是缓冲区的视图**。
|
||||
|
||||
下表总结了前几屏中出现的命令。
|
||||
|
||||
键绑定 操作(命令)
|
||||
C-x C-f find-file
|
||||
C-x C-s save-buffer
|
||||
C-x C-w write-file
|
||||
C-x 2 split-window-vertically
|
||||
C-x 3 split-window-horizontally
|
||||
C-x o other-window
|
||||
C-x 1 delete-other-windows
|
||||
C-x C-b list-buffers
|
||||
C-x b switch-to-buffer
|
||||
C-x k kill-buffer
|
||||
|
||||
===== 简短的深入学习 =====
|
||||
|
||||
==== 模式 ====
|
||||
|
||||
__模式是在特定的内容类型的环境下 Emacs 特性的表达方法__。也就是说,缩进的表现在 C 源代码文件和在 HTML 文件中是不同的,在给您的老板的信中的表现也是不同的。每个缓冲区的__主要模式__显示在状态行上缓冲区名字的右边的括弧中。
|
||||
|
||||
有两种不同的模式类型:**主要和次要**。每次只有一个主要模式被激活,但它们**修改次要模式的解释**。例如,在大多数的代码编写中,缩进参照的仅是上一行。在 .txt 文档中按 Tab 键(文本模式已被自动调用),一个制表符被插入并显示为 8 列。
|
||||
|
||||
而在这个 XML 文档中,Emacs 缺省地调用 SGML 模式。在这里,按 Tab 键有效果的前提是上一行的开头有空格,在这种情况下,光标被放在上一行第一个不是空格的匹配的那一列,距离由空格字符填充,而不是一个制表符。
|
||||
|
||||
**缩进表现是次要模式的一部分**,它的活动由当前调用的主要模式来修改。模式还可以直接表现为语法突出显示的区别和文本被自动填充的方式的区别。
|
||||
|
||||
==== 再谈模式 ====
|
||||
|
||||
主要模式通常由 Emacs 根据**文件名**或(有时)**文件内容**来正确设置。您可以明确地设置缓冲区的模式,方法是输入 M-x 加有效的模式名。
|
||||
|
||||
例如,如果我打开一个叫 bob.txt 的文件,缓冲区会以** text-mode **打开它。为了转入 c-mode,我输入 __M-x c-mode__。根据消息缓冲区,这实际上为我调用的是 cc-mode 并在状态栏上显示为 C Abbrev)。
|
||||
|
||||
列出 Emacs 自动识别的所有主要模式的方法是输入 M-x describe-variable,按 Enter,然后在小缓冲区的提示符后输入 **auto-mode-alist**。一些我常用的模式包括文本、c 和 SGML,有时还用 LISP。
|
||||
|
||||
|
||||
==== 编译代码 ====
|
||||
|
||||
看了模式列表后,您显然可在 Emacs 中做很多事。然而最重要的是,__Emacs 是程序员的编辑器__。在 Emacs 环境中,您可以编写代码、编译、调试和测试软件,还可以做其它事。在这里,我不准备讲所有的这些主题,但让我们假设我已用 C 语言写了一个典型的 Hello World 之类的程序。
|
||||
|
||||
当我输入该程序并把缓冲区存到磁盘上后,我输入 __M-x compile__,于是,在小缓冲区中出现这样的提示符:Compile command:,后面可能还有缺省值。我输入 __gcc -o hello hello.c__ 并按 Enter。一个编译窗口被打开,它包含如下的文本:
|
||||
|
||||
cd /home/bilbrey/
|
||||
gcc -o hello hello.c
|
||||
|
||||
Compilation finished at Sun Mar 17 16:18:55
|
||||
|
||||
|
||||
为了查看我的程序能否运行,我从 Emacs 中运行它:__M-! ~/hello__。在小缓冲区中,我的输出是:“Hello, World!”
|
||||
|
||||
|
||||
==== Emacs 和 LISP ====
|
||||
|
||||
Emacs 这个名字有点象 Editor MACroS 的缩写。所以,Emacs 中的另一经常的代码编写体验涉及**在 LISP 的 Emacs 版本中设置变量和写宏**。__LISP 被嘲讽为“Lots of Insane Stupid Parentheses(许多神经病的愚蠢的括弧)”的缩写__,但它在很多方面是一门成功的语言,尤其是 Emacs。
|
||||
|
||||
Emacs 变量可在命令行中设置(如果您知道它们的名字和适当的值),设置方法是输入 __M-x set-variable__ ,然后在提示符后输入变量名和它的新值。您也可以__直接通过求它们的值来设置变量__。为此,我建议使用草稿缓冲区。从“LinuxDoc Emacs Beginner HOWTO”中借用一个示例(请参阅参考资料),让我们修改自动填充模式(即词语自动换行)的宽度:
|
||||
|
||||
__(setq fill-column 20)__
|
||||
|
||||
|
||||
输入后,把**光标留在行末**,输入 __C-x C-e __来求表达式的值。在小缓冲区中结果是 20。测试它的方法是使用 __M-q(fill-paragraph)__命令来重新格式化文本的一个段落。
|
||||
|
||||
随着您学习的深入,您还可以编写实现新功能的代码。通过试验找到您喜欢的设置。然后,您可以把它们放在您的 ~/.emacs 定制文件中,以便今后使用。
|
||||
|
||||
|
||||
==== Emacs 中的连接 ====
|
||||
|
||||
电子邮件和 Web 浏览工具已被构建到 Emacs 中。发送新的电子邮件消息的第一步是输入 __C-x m__。当您写完后,用 __C-x C-s__ 保存并发送您的消息。阅读邮件要稍稍复杂些。 参考资料 at the end of the tutorial Web 浏览的实现是通过把 URL 发送到外部的浏览器或直接在 Emacs 中运行象 Lynx 这样的文本模式浏览器。输入 __M-x browse-url-lynx-emacs __来调用 Lynx,输入 URL,就可以了。下面运行的示例是在一个终端模式 Emacs 会话中的电子邮件撰写和浏览。
|
||||
|
||||
==== 不停地工作,不能玩…… ====
|
||||
|
||||
当然,游戏已被构建到 Emacs 中,有“Towers of Hanoi”和“Life through a variant of Tetris”(tm),还有古老的“Adventure”的另一版本,如下面的清单所演示的:
|
||||
|
||||
E/W Dirt road
|
||||
You are on the continuation of a dirt road. There are more trees on
|
||||
both sides of you. The road continues to the east and west.
|
||||
There is a large boulder here.
|
||||
>look at boulder
|
||||
It is just a boulder. It cannot be moved.
|
||||
>climb boulder
|
||||
You can't climb that.
|
||||
...
|
||||
|
||||
|
||||
甚至还有著名的 Rogerian 心理程序,Eliza,在早上三点,无论您怎样做都无法编译时,它能让您通过难关。输入__ M-x doctor __。它比任何 900 号码都便宜得多,是吗?
|
||||
|
||||
总结、参考资料和反馈
|
||||
|
||||
===== 把叉子插入其中…… =====
|
||||
|
||||
我们已完成!祝贺您漂亮地完成任务。我在很多年前学用 Emacs 时,我发现它有点……恐怖。我已尽力为您打下一个好的基础,使您掌握这个强大的编辑工具的概念和使用。
|
||||
|
||||
__使用 Emacs。在其中生活一段时间,学会喜欢它。像所有的复杂程序,您得花些时间才能完全理解它,但这种努力是值得的:您将熟练掌握一个最常见的 UNIX 编程实用程序并学会肯定适应市场的技能。__
|
||||
232
Zim/Utils/emacs/C,C++.txt
Normal file
@@ -0,0 +1,232 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-05T22:37:02+08:00
|
||||
|
||||
====== 在Emacs下用C/C++编程 ======
|
||||
2010年10月25日 lertsau 发表评论 阅读评论
|
||||
|
||||
1 参考文献
|
||||
2 序
|
||||
3 基本流程
|
||||
4 基本环境设置
|
||||
4.1 编辑环境配置
|
||||
4.2 自动补齐
|
||||
5 编译和调试程序
|
||||
6 阅读代码
|
||||
|
||||
===== 1 参考文献 =====
|
||||
|
||||
按照惯例,我写的文章在最开始处放参考文献。
|
||||
|
||||
hhuu @ newsmth 的《Emacs的日常生活》
|
||||
emacs 的文档
|
||||
emacs 相关插件的文档
|
||||
|
||||
===== 2 序 =====
|
||||
|
||||
用emacs写程序也有5个年头了,深切地体会到Emacs的强大。程序员有三种,一种是用vi的,一种是用emacs的,还有一种是其他。或许有些夸张,但也颇能体现出emacs在程序员中的地位。
|
||||
|
||||
emacs最大的问题在于入门门槛较高。它看起来和多数人想象中的IDE相差甚远,很多人看到emacs的第一眼就觉得它是个记事本(还是个非常难用的记事本),稍微好些的往往觉得emacs也就是个ultraEditor而已,真是暴殄天物了。
|
||||
|
||||
我是个懒人,不喜欢记太多的快捷键,相信很多人和我一样。所以从我后面的叙述可以看出来,除了常用的命令都是快捷键外,其他命令多数都是用M-x执行或者用鼠标点菜单。这仅仅是个人风格问题,先说明一下。
|
||||
|
||||
我的基本编程环境是:
|
||||
|
||||
Debian GNU/Linux sid 操作系统
|
||||
Gnome 2.10.0 桌面环境
|
||||
GUN Emacs 23.0.0.1 for debian
|
||||
使用 Gnu tool chains(gcc,make,gdb等等)
|
||||
|
||||
后面的叙述都基于上述环境。另外,本文主要针对C/C++程序开发,对其他语言有些也适用,从难度上说,本文主要针对入门者。
|
||||
|
||||
本文肯定会有很多错误,请指正, 谢谢。
|
||||
|
||||
===== 3 基本流程 =====
|
||||
|
||||
写C++程序基本上是这么几个步骤:
|
||||
|
||||
编辑代码
|
||||
编写Makefile
|
||||
编译代码,修改编译错误
|
||||
调试代码,修改逻辑错误
|
||||
|
||||
当然,往往还需要阅读别人的代码。
|
||||
|
||||
根据上述步骤,本文主要针对以下几个方面:
|
||||
|
||||
配置Emacs,建立便利的代码编辑环境和Makefile编写环境。
|
||||
在Emacs中编译代码,并修改编译错误。
|
||||
在Emacs中配合GDB调试程序。
|
||||
利用cscope和ecb在emacs中阅读代码。
|
||||
|
||||
===== 4 基本环境设置 =====
|
||||
|
||||
==== 4.1 编辑环境配置 ====
|
||||
|
||||
要写C++程序,当然要用到cc-mode插件。CC-Mode原本是支持C语言的,但现在也能支持很多语言,比如 C++,Java,Objective-C,CORBA,AWK,Pike等等。CC-Mode是gnu-emacs的标准插件。如果您要求不高,那么默认的配置或许就能满足。CC-Mode的各种行为都可以自由地定制,您可以参考这里的文档:CC-Mode参考文档
|
||||
|
||||
这里是我的.emacs文件中关于CC-Mode配置的部分,仅供参考:
|
||||
|
||||
;;;; CC-mode配置 http://cc-mode.sourceforge.net/
|
||||
(require 'cc-mode)
|
||||
(c-set-offset 'inline-open 0)
|
||||
(c-set-offset 'friend '-)
|
||||
(c-set-offset 'substatement-open 0)
|
||||
|
||||
;;;;我的C/C++语言编辑策略
|
||||
|
||||
(defun my-c-mode-common-hook()
|
||||
(setq tab-width 4 indent-tabs-mode nil)
|
||||
;;; hungry-delete and auto-newline
|
||||
(c-toggle-auto-hungry-state 1)
|
||||
;;按键定义
|
||||
(define-key c-mode-base-map [(control \`)] 'hs-toggle-hiding)
|
||||
(define-key c-mode-base-map [(return)] 'newline-and-indent)
|
||||
(define-key c-mode-base-map [(f7)] 'compile)
|
||||
(define-key c-mode-base-map [(meta \`)] 'c-indent-command)
|
||||
;; (define-key c-mode-base-map [(tab)] 'hippie-expand)
|
||||
(define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
|
||||
(define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
|
||||
|
||||
注意一下,上面最后两行是代码自动补齐的快捷键。后面我会提到代码自动补齐。
|
||||
|
||||
;;预处理设置
|
||||
(setq c-macro-shrink-window-flag t)
|
||||
(setq c-macro-preprocessor "cpp")
|
||||
(setq c-macro-cppflags " ")
|
||||
(setq c-macro-prompt-flag t)
|
||||
(setq hs-minor-mode t)
|
||||
(setq abbrev-mode t)
|
||||
)
|
||||
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
|
||||
;;;;我的C++语言编辑策略
|
||||
(defun my-c++-mode-hook()
|
||||
(setq tab-width 4 indent-tabs-mode nil)
|
||||
(c-set-style "stroustrup")
|
||||
;; (define-key c++-mode-map [f3] 'replace-regexp)
|
||||
)
|
||||
|
||||
==== 4.2 自动补齐 ====
|
||||
|
||||
自动补齐通常用的都是hippie-expand,我也用了很长时间。不过有时候会觉得这个自动补齐“傻”了一点,常会补齐出一些毫不相干的东西,因为hippie-expand是根据你敲过的词和kill-ring等进行判断的,并不对程序语法进行分析。
|
||||
|
||||
所以你还需要安装一个代码分析工具,然后把它加进hippie-expand的扩展策略里去。我们可以用semantic。实际上,**hippie-expand+semantic**是我所发现的最好的选择了,如果您有更好的,请您也告诉我一声:)
|
||||
|
||||
Semantic是CEDET 中的一个工具,CEDET是Collection of Emacs Development Environment Tools的缩写,它包含了好几个工具,都挺不错的。可惜我只会用其中两个。
|
||||
|
||||
您可以在.emacs中对Semantic进行配置,下面是我的.emacs相关的配置,仅供参考:
|
||||
|
||||
导入cedet:
|
||||
(load-file "~/lib/emacs-lisp/cedet-1.0pre3/common/cedet.el")
|
||||
|
||||
配置Semantic的检索范围:
|
||||
|
||||
(setq semanticdb-project-roots
|
||||
(list
|
||||
(expand-file-name "/")))
|
||||
|
||||
自定义自动补齐命令,这部分是抄hhuu的,如果在单词中间就补齐,否则就是tab。
|
||||
|
||||
|
||||
(defun my-indent-or-complete ()
|
||||
(interactive)
|
||||
(if (looking-at "\\>")
|
||||
(hippie-expand nil)
|
||||
(indent-for-tab-command))
|
||||
)
|
||||
|
||||
(global-set-key [(control tab)] 'my-indent-or-complete)
|
||||
|
||||
hippie的自动补齐策略,优先调用了senator的分析结果:
|
||||
|
||||
(autoload 'senator-try-expand-semantic "senator")
|
||||
|
||||
(setq hippie-expand-try-functions-list
|
||||
'(
|
||||
senator-try-expand-semantic
|
||||
try-expand-dabbrev
|
||||
try-expand-dabbrev-visible
|
||||
try-expand-dabbrev-all-buffers
|
||||
try-expand-dabbrev-from-kill
|
||||
try-expand-list
|
||||
try-expand-list-all-buffers
|
||||
try-expand-line
|
||||
try-expand-line-all-buffers
|
||||
try-complete-file-name-partially
|
||||
try-complete-file-name
|
||||
try-expand-whole-kill
|
||||
)
|
||||
)
|
||||
|
||||
注意一下我前面CC-Mode配置中有这么两行:
|
||||
|
||||
(define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
|
||||
(define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
|
||||
|
||||
这样,我们在CC-Mode中就可以调用自定义的hippie补全了,快捷键是Tab。
|
||||
|
||||
另外,我还把快捷键“Alt + / ”绑定到了semantic-ia-complete-symbol-menu命令上,这是semantic的命令,它会根据分析结果弹出补齐的菜单,效果如图显示:
|
||||
|
||||
|
||||
CEDET中还有一个不错的工具是speedbar,你可以用它在多个文件中快速切换。在我的.emacs配置文件里,我把speedbar关联到了F5上:
|
||||
|
||||
(global-set-key [(f5)] 'speedbar)
|
||||
|
||||
这样用F5就可以调出speedbar,效果如下:
|
||||
|
||||
不过说实话,我自己很少用到speedbar,我通常都是**用dired配合bookmark**使用:)
|
||||
|
||||
===== 5 编译和调试程序 =====
|
||||
|
||||
按上面的配置,写完程序和Makefile文件后,在Emacs源代码窗口中按F7就可以进行编译。因为在my-c-mode-common-hook()函数里,有这么一行:
|
||||
|
||||
(define-key c-mode-base-map [(f7)] 'compile)
|
||||
|
||||
默认情况下,emacs的compile命令是调用make -k,我把它改成了make。你也可以把它改成其他的,比如gcc之类的。改下面的“make”就行了。
|
||||
|
||||
'(compile-command "make")
|
||||
|
||||
Emacs会划分一个窗格显示编译的消息,在编译结束后,emacs会自动将编译器的输出和程序关联起来,告诉你第几行的程序有问题。直接在出错的行号上按Enter,就可以跳转到相应文件的相应行。其实我通常都是用鼠标中键去点出错行号:)
|
||||
|
||||
搞定了编译错误后,接着要和逻辑错误斗争了。其实对简单的程序来说,**把中间结果打印到终端是最简单好用的调试办法**:)不过稍微复杂点的程序就会晕菜了,这时我们就需要拿gdb跟踪程序流程了。
|
||||
|
||||
你用下面的命令就可以启动gdb了。
|
||||
|
||||
M-x gdb
|
||||
|
||||
通常我喜欢进入**gdb-many-windows**模式,这样就会把一个Frame划分为5个窗格,同时显示:gdb命令窗口,当前局部变量,程序文本,调用栈和断点。
|
||||
|
||||
gdb的命令就不在这里说了,它的文档几乎到处都是。emacs把gdb的命令和快捷键做了绑定,对于常用的命令,还是输入快捷键比较方便。比如,C-c C-n是Next line,C-c C-s是step in,其实用的最多的快捷键也就是这两个。
|
||||
|
||||
===== 6 阅读代码 =====
|
||||
|
||||
在emacs下读代码通常有三种工具,最简单的是**etags**,最复杂的是**ecb**(emacs code browser),位于中间的是**cscope**。
|
||||
|
||||
etags和ctags一样,只不过前者是用于emacs的,后者是用于vi的。我个人觉得etags功能稍稍显得不够用一点,当然,也可能是我用的不好:) 欢迎大牛指导。
|
||||
|
||||
使用tags之前要先对源代码分析建立tags文件,在代码所在目录中运行:etags -R 即可。
|
||||
|
||||
我常用的就这几个命令和快捷键:
|
||||
|
||||
M-x visit-tags-table <RET> FILE <RET> 选择tags文件
|
||||
M-. [TAG] <RET> 访问标签
|
||||
M-* 返回
|
||||
C-u M-. 寻找标签的下一个定义
|
||||
|
||||
cscope是我感觉比较合适的一个工具。它其实是一个独立的软件,完全可以脱离vi和emacs使用。但是结合emacs的强大功能,cscope就显得更加方便了。GNU Emacs默认自带cscope的支持。**在使用之前,cscope也需要对代码进行索引**。在emacs中可以这样做:
|
||||
|
||||
C-c s a 设定初始化的目录,一般是你代码的根目录
|
||||
C-s s I 对目录中的相关文件建立列表并进行索引
|
||||
|
||||
建完索引之后,你就可以用cscope在代码里游荡了。常用的一些命令如下:
|
||||
|
||||
C-c s s 序找符号
|
||||
C-c s g 寻找全局的定义
|
||||
C-c s c 看看指定函数被哪些函数所调用
|
||||
C-c s C 看看指定函数调用了哪些函数
|
||||
C-c s e 寻找正则表达式
|
||||
C-c s f 寻找文件
|
||||
C-c s i 看看指定的文件被哪些文件include
|
||||
|
||||
上面这些快捷键其实我自己也常常记不全,没关系,抬头看看上面的菜单栏,有一栏就是Cscope,这些命令里头都有:)
|
||||
|
||||
37
Zim/Utils/emacs/DocViewMode.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-19T20:37:16+08:00
|
||||
|
||||
====== DocViewMode ======
|
||||
Created Friday 19 August 2011
|
||||
DocViewMode is another file mode viewer like DviViewMode which adds support for PDF and PS files written by TassiloHorn. It’s official part of Emacs 23.
|
||||
|
||||
Conversion is done with ghostscript and various other tools. It even supports regexp search in documents.
|
||||
|
||||
To get it it’s best to install Emacs 23 (the current CVS HEAD).
|
||||
|
||||
You can get a snapshot of doc-view.el at doc-view.el.
|
||||
|
||||
The homepage of DocViewMode is http://www.tsdh.de/cgi-bin/wiki.pl/doc-view.el.
|
||||
|
||||
This can be customized via:
|
||||
|
||||
M-x customize-group doc-view RET
|
||||
|
||||
Required Software
|
||||
|
||||
__ Ghostscript.__
|
||||
Other Things?
|
||||
|
||||
Cygwin
|
||||
|
||||
Emacs 23 Instructions.
|
||||
|
||||
1. Install several packages:
|
||||
|
||||
xpdf
|
||||
ghostscript
|
||||
|
||||
2. Restart Emacs.
|
||||
|
||||
3. It should just work.
|
||||
89
Zim/Utils/emacs/Emacs_Python_completion.txt
Normal file
@@ -0,0 +1,89 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-11-20T00:17:13+08:00
|
||||
|
||||
====== Emacs Python completion ======
|
||||
Created Sunday 20 November 2011
|
||||
http://www.rwdev.eu/articles/emacspyeng
|
||||
C
|
||||
Emacs Python completion
|
||||
|
||||
The purpose of this package is to support Python code completion and to make easier to use Python documentation using Emacs.
|
||||
There are available following features:
|
||||
|
||||
code completion hitting <TAB> (or <C-M-i>) key: e.g.: time.cl<TAB> -> time.clock time.<TAB> -> list of possible choices
|
||||
description of the element (function/module/class/keyword) at the point hitting <F1> key
|
||||
hitting '(' and ',' shows funtion signature e.g.: time.strftime( -> strftime(format[, tuple]) -> string
|
||||
<F2> getting signature of a given function name
|
||||
<F3> getting description of a given element name
|
||||
|
||||
=============== Python 2.x =================
|
||||
Requirements
|
||||
|
||||
Pymacs the latest version from trunk or prepared package for Python2.x
|
||||
python-mode or python-mode.el included in this package
|
||||
|
||||
Installation
|
||||
|
||||
if you choose original Pymacs install according to instructions
|
||||
if you choose my Pymacs package: copy file pymacs.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp), and directory Pymacs on PYTHONPATH (e.g. /usr/lib/python2.7/site-packages)
|
||||
copy files python-mode.el and pycomplete.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp).
|
||||
copy file pycomplete on your PYTHONPATH (e.g. /usr/lib/python2.7/site-packages)
|
||||
Copy the following settings to your .emacs file
|
||||
|
||||
# .emacs
|
||||
|
||||
;; python-mode settings
|
||||
(setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
|
||||
(setq interpreter-mode-alist(cons '("python" . python-mode)
|
||||
interpreter-mode-alist))
|
||||
;; path to the python interpreter, e.g.: ~rw/python27/bin/python2.7
|
||||
(setq py-python-command "python")
|
||||
(autoload 'python-mode "python-mode" "Python editing mode." t)
|
||||
|
||||
;; pymacs settings
|
||||
(setq pymacs-python-command py-python-command)
|
||||
(autoload 'pymacs-load "pymacs" nil t)
|
||||
(autoload 'pymacs-eval "pymacs" nil t)
|
||||
(autoload 'pymacs-apply "pymacs")
|
||||
(autoload 'pymacs-call "pymacs")
|
||||
|
||||
(require 'pycomplete)
|
||||
|
||||
# end of .emacs
|
||||
|
||||
=============== Python 3.x =================
|
||||
Requirements
|
||||
|
||||
Pymacs the latest version from trunk or prepared package for Python3.x
|
||||
python-mode or python-mode.el included in this package
|
||||
|
||||
Installation
|
||||
|
||||
if you choose original Pymacs install according to instructions
|
||||
if you choose my Pymacs package: copy file pymacs.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp), and directory Pymacs on PYTHONPATH (e.g. /usr/lib/python3.1/site-packages)
|
||||
copy files python-mode.el and pycomplete.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp).
|
||||
copy file pycomplete3 on your PYTHONPATH (e.g. /usr/lib/python3.1/site-packages)
|
||||
Copy the following settings to your .emacs file
|
||||
|
||||
# .emacs
|
||||
|
||||
;; python-mode settings
|
||||
(setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
|
||||
(setq interpreter-mode-alist(cons '("python" . python-mode)
|
||||
interpreter-mode-alist))
|
||||
;; path to the python interpreter, e.g.: ~rw/python31/bin/python3
|
||||
(setq py-python-command "python3")
|
||||
(autoload 'python-mode "python-mode" "Python editing mode." t)
|
||||
|
||||
;; pymacs settings
|
||||
(setq pymacs-python-command py-python-command)
|
||||
(autoload 'pymacs-load "pymacs" nil t)
|
||||
(autoload 'pymacs-eval "pymacs" nil t)
|
||||
(autoload 'pymacs-apply "pymacs")
|
||||
(autoload 'pymacs-call "pymacs")
|
||||
|
||||
(require 'pycomplete)
|
||||
|
||||
# end of .emacs
|
||||
|
||||
3327
Zim/Utils/emacs/Emacs_Tips.txt
Normal file
179
Zim/Utils/emacs/Emacs_setup_for_python_development.txt
Normal file
@@ -0,0 +1,179 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-09T17:11:32+08:00
|
||||
|
||||
====== Emacs setup for python development ======
|
||||
Created Monday 09 January 2012
|
||||
http://www.yilmazhuseyin.com/blog/dev/emacs-setup-python-development/
|
||||
|
||||
This is the follow up for basic emacs setup post. In this post I will explain how to update your emacs setup for python development. I will cover
|
||||
|
||||
* pymacs (Python binding for emacs. This is a ropemacs dependency)
|
||||
* rope (Python refactoring library.This is a ropemacs dependency)
|
||||
* ropemacs (Rope bindings for emacs)
|
||||
* rope-mode (Minor mode for ropemacs)
|
||||
* pyflakes (passive checker of Python programs)
|
||||
* flymake (an on-the-fly syntax checker for GNU Emacs)
|
||||
* flymake-mode (Minor mode for flymake)
|
||||
* pyflakes error format script
|
||||
* autocomplete rope integration
|
||||
|
||||
Install pymacs
|
||||
|
||||
From emacs wiki I found http://pymacs.progiciels-bpi.ca/ page and download pymacs. I also read the manual from this page which has directions to how you can install it. Here is how I did it.
|
||||
|
||||
Untared downloaded file and did a “$sudo python setup.py install” in it.
|
||||
Copy pymacs.el to somewhere in your emacs loadpath. I put it in ~/.emacs.d/plugins/pymacs.el
|
||||
|
||||
I also added the following to .emacs file like manual says
|
||||
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
|
||||
|
||||
|
||||
(autoload 'pymacs-apply "pymacs")
|
||||
(autoload 'pymacs-call "pymacs")
|
||||
(autoload 'pymacs-eval "pymacs" nil t)
|
||||
(autoload 'pymacs-exec "pymacs" nil t)
|
||||
(autoload 'pymacs-load "pymacs" nil t)
|
||||
;;(eval-after-load "pymacs"
|
||||
;; '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
|
||||
|
||||
Install rope
|
||||
|
||||
I googled for rope and found this page http://rope.sourceforge.net/ and found rope-0.9.3.tar.gz. I untared it and did
|
||||
|
||||
1
|
||||
|
||||
|
||||
|
||||
$sudo python setup.py install
|
||||
|
||||
Install ropemacs
|
||||
|
||||
I found this page. From there, I downloaded ropemacs repository snapshot. When you get it just untar it and run
|
||||
|
||||
1
|
||||
|
||||
|
||||
|
||||
sudo python setup.py install
|
||||
|
||||
After that point I read README.txt that was included in untarred directory. I added following script to .emacs file as README.txt file suggested
|
||||
|
||||
1
|
||||
2
|
||||
|
||||
|
||||
|
||||
(require 'pymacs)
|
||||
(pymacs-load "ropemacs" "rope-")
|
||||
|
||||
Install rope-mode
|
||||
|
||||
From ropemacs page I gave in previouse section, I found ropemode repository snapshot and downloaded it. After I untarred it, I called following command as usual.
|
||||
|
||||
1
|
||||
|
||||
|
||||
|
||||
sudo python setup.py install
|
||||
|
||||
Install pyflakes
|
||||
|
||||
Google for pyflakes and when you find the project site download pyflakes from there. After that untarred it and inside untarred directory call
|
||||
|
||||
1
|
||||
|
||||
|
||||
|
||||
sudo python setup.py install
|
||||
|
||||
Install flymake
|
||||
|
||||
UPDATE: As Stéphane Raimbault suggested in the comments. flymake.el is already added in emacs. So you can skip downloading flymake.el.
|
||||
|
||||
Google for flymake, find project site and download it. When you get flymake.el put it somewhere on your emacs load path.(~/.emacs.d/plugins/flymake.el)
|
||||
Add flymake mode
|
||||
|
||||
After that, you should configure flymake to work with pyflakes like emacs-wiki explains. Alternatively you can go to flymake-mode page to get the script.
|
||||
|
||||
In my case I added the following script and put it to my .emacs file
|
||||
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
|
||||
|
||||
|
||||
(when (load "flymake" t)
|
||||
(defun flymake-pyflakes-init ()
|
||||
(let* ((temp-file (flymake-init-create-temp-buffer-copy
|
||||
'flymake-create-temp-inplace))
|
||||
(local-file (file-relative-name
|
||||
temp-file
|
||||
(file-name-directory buffer-file-name))))
|
||||
(list "pyflakes" (list local-file))))
|
||||
|
||||
(add-to-list 'flymake-allowed-file-name-masks
|
||||
'("\\.py\\'" flymake-pyflakes-init)))
|
||||
|
||||
(add-hook 'find-file-hook 'flymake-find-file-hook)
|
||||
|
||||
Add flymake errors to mini-buffer
|
||||
|
||||
Flymake marks the errors with red. But it does not prints the error on screen. So I found a script that writes the errors on the current line to mini-buffer. Here is the script that I added to my .emacs file
|
||||
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
|
||||
|
||||
|
||||
(defun my-flymake-show-help ()
|
||||
(when (get-char-property (point) 'flymake-overlay)
|
||||
(let ((help (get-char-property (point) 'help-echo)))
|
||||
(if help (message "%s" help)))))
|
||||
|
||||
(add-hook 'post-command-hook 'my-flymake-show-help)
|
||||
|
||||
Add autocomplete rope integration
|
||||
|
||||
If you have auto-complete in your emacs setup, you can actually integrate auto-complete with rope. To do this, I found this page. From there I downloaded script for rope-autocomplete integration. Here is the script that I added to my .emacs file.
|
||||
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
|
||||
|
||||
|
||||
(ac-ropemacs-initialize)
|
||||
(add-hook 'python-mode-hook
|
||||
(lambda ()
|
||||
(add-to-list 'ac-sources 'ac-source-ropemacs)))
|
||||
|
||||
Note for django developers
|
||||
|
||||
If you are developing django apps you might want to cover emacs basic setup and emacs web setup post with this one. All three posts covers total of my emacs setup for developing django applications.
|
||||
|
||||
Date: 6 Mayıs 2011 | Tags: python, django, linux, emacs, installation, | Categories: emacs,
|
||||
@@ -0,0 +1,95 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-09T20:12:06+08:00
|
||||
|
||||
====== Pylookup ======
|
||||
Created Monday 09 January 2012
|
||||
http://taesoo.org/Opensource/Pylookup
|
||||
|
||||
Pylookup is a mode to** search python documents **especially within emacs.
|
||||
|
||||
===== Usage =====
|
||||
1. M-x pylookup-lookup
|
||||
|
||||
{{./1-lookup.png}}
|
||||
|
||||
M-x pylookup-lookup, (set your local key map)
|
||||
|
||||
2. Ido autocompletion
|
||||
{{./2-ido.png}}
|
||||
|
||||
Interactive do interface to search keywords
|
||||
C-r, C-s : next/prev match
|
||||
|
||||
3. Search results
|
||||
{{./3-search.png}}
|
||||
|
||||
Results of searching a keyword
|
||||
n/p : next/prev line
|
||||
C-v,M-v : scroll up/down
|
||||
q : quit
|
||||
Space/Enter : lookup document
|
||||
|
||||
4.Read in your browser
|
||||
|
||||
{{./5-browsing.png}}
|
||||
|
||||
You can see the proper python document in your favorite browser, w3m, firefox, ie or whatever.
|
||||
|
||||
===== Install =====
|
||||
|
||||
==== Checkout ====
|
||||
git clone http://github.com/tsgates/pylookup.git
|
||||
Edit .emacs
|
||||
|
||||
;; add pylookup to your loadpath, ex) "~/.lisp/addons/pylookup"
|
||||
(setq pylookup-dir "[PATH]")
|
||||
(add-to-list 'load-path pylookup-dir)
|
||||
;; load pylookup when compile time
|
||||
(eval-when-compile (require 'pylookup))
|
||||
|
||||
;; set executable file and db file
|
||||
(setq pylookup-program (concat pylookup-dir "/pylookup.py"))
|
||||
(setq pylookup-db-file (concat pylookup-dir "/pylookup.db"))
|
||||
|
||||
;; to speedup, just load it on demand
|
||||
(autoload 'pylookup-lookup "pylookup"
|
||||
"Lookup SEARCH-TERM in the Python HTML indexes." t)
|
||||
(autoload 'pylookup-update "pylookup"
|
||||
"Run pylookup-update and create the database at `pylookup-db-file'." t)
|
||||
|
||||
Change [PATH] variable to proper path where you installed pylookup
|
||||
Add above code in your .emacs
|
||||
|
||||
===== Preferences =====
|
||||
|
||||
==== • Keybinding ====
|
||||
(global-set-key __"\C-ch"__ 'pylookup-lookup) #这是缺省的绑定
|
||||
|
||||
==== • Lookup downloaded documents ====
|
||||
Update Database (In repository, there is database to lookup online document, but slow to load in a browser)
|
||||
|
||||
$ cd ~/.lisp/addons/pylookup
|
||||
$ ./pylookup.py -u file:///home/tsgates/.lisp/addons/pylookup/python-2.6.2-docs-html
|
||||
$ ./pylookup.py -l test
|
||||
COMPARISON_FLAGS (in module doctest) [lib];file:///home/tsgates/.lisp/addons/pylookup...
|
||||
|
||||
* Move to pylookup directory
|
||||
* Execute pylookup.py with your absolute python document path, download from here
|
||||
* Test by executing pylookup.py -l test and check pylookup indicating proper path you set
|
||||
|
||||
==== • Default browser ====
|
||||
;; __w3m,系统需要安装w3m,同时还需要安装emacs-3m插件__
|
||||
(setq browse-url-browser-function 'w3m-browse-url)
|
||||
(setq browse-url-default-browser "firefox.exe") ;; firefox in M$ Windows
|
||||
|
||||
==== • Numpy Support ====
|
||||
self.list_entry = False" in IndexProcessor.__init__
|
||||
|
||||
|
||||
===== Acknowledgements =====
|
||||
|
||||
Martin Blais's haddoc mode: http://furius.ca/haddoc
|
||||
Github: http://github.com/tsgates/pylookup
|
||||
This code is distributed under the GNU GPL v.2.0
|
||||
|
||||
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 158 KiB |
|
After Width: | Height: | Size: 186 KiB |
|
After Width: | Height: | Size: 309 KiB |
@@ -0,0 +1,49 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-09T19:27:11+08:00
|
||||
|
||||
====== pyflakes ======
|
||||
Created Monday 09 January 2012
|
||||
http://www.plope.com/Members/chrism/flymake-mode
|
||||
|
||||
I found something useful! I found something useful!
|
||||
|
||||
Flymake is an on-the-fly syntax checker for Emacs. Essentially every so often it runs your buffer through a language-specific__ syntax checker__ and __highlights code errors__ and __warnings__ in a different color. I can hear "real" IDE people laughing at me now, but for better or worse, I will probably use Emacs until I die; not because I like it particularly, but because it's the only thing my fingers know how to use, thus searching for better tools is pointless.
|
||||
|
||||
Out of the box, Flymake__ can't __analyze Python code, but it helpfully has a plugin system. It allows you to plug in, for example, __pylint or pyflakes__ or probably any other checker. I use pyflakes regularly.
|
||||
whine[wain]n.闹声, 抱怨, 牢骚 v.哭诉, 发牢骚
|
||||
Pyflakes is excellent, it basically __just whines when you're using a name that hasn't been defined __(an indictment of your lack of testing for that code path) or __you've imported a name twice__, or __you're not using a name that you've imported.__
|
||||
|
||||
http://developer.51cto.com/art/201003/190888.htm
|
||||
Python CST 和AST 类似,都是语法分析所获得的中间结果。他们的不同之处在于,CST直接对应语法分析的匹配的过程,是直接生成的,含有大量冗余信息。而AST省略了中间的冗余信息,直接对应实际的语义,也就是分析的结果。
|
||||
|
||||
Importantly, it walks the Python AST rather than trying to import things (which other checkers seem to tend to try to do), so it's fast and using it has no side effects. I tend to__ use pyflakes as a before-checkin sanity check__ to make sure I haven't forgotten to remove an import, so it made sense to try to fit it into my editor.
|
||||
|
||||
Here's what I did to get it working. As I said, it's all cargo-culted, consistent with the rest of my Emacs configuration.
|
||||
|
||||
* I downloaded flymake.el and put it in a directory in my emacs load-path. I'm not even sure I needed to do this, I think it ships with Emacs now. Who knows, it works.
|
||||
* I made sure I could invoke pyflakes as "pyflakes" (I put the pyflakes executable on my PATH).
|
||||
pyflakes是一个可执行程序,同时还有相应的python模块
|
||||
* I added some (more) inscrutable stuff to my .emacs file
|
||||
|
||||
The stuff I added to the .emacs file:
|
||||
|
||||
(when (load "flymake" t)
|
||||
(defun flymake-pyflakes-init ()
|
||||
(let* ((temp-file (flymake-init-create-temp-buffer-copy
|
||||
'flymake-create-temp-inplace))
|
||||
(local-file (file-relative-name
|
||||
temp-file
|
||||
(file-name-directory buffer-file-name))))
|
||||
(list "pyflakes" (list local-file))))
|
||||
|
||||
(add-to-list '__flymake-allowed-file-name-masks __
|
||||
'("\\.py\\'" flymake-pyflakes-init)))
|
||||
|
||||
(add-hook 'find-file-hook 'flymake-find-file-hook)
|
||||
|
||||
The first stanza tells flymake to** use pyflakes on .py files when in flymake-mode**. The second tells emacs to always use flymake as a __minor mode__ when loading buffers so I don't have to type "M-x flymake-mode" to get syntax checking when I load a buffer.
|
||||
|
||||
And now! It works. I don't know how it works but it does. The below picture proves it (I import traceback but I don't use it).
|
||||
|
||||
And thus verify come the inane checkins for things I'm working on now that read "remove unused import".
|
||||
@@ -0,0 +1,73 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-09T22:37:53+08:00
|
||||
|
||||
====== python-mode and ipython ======
|
||||
Created Monday 09 January 2012
|
||||
https://bugs.launchpad.net/python-mode/+bug/912919
|
||||
|
||||
rev 752 breaks ipython
|
||||
|
||||
python-mode.el
|
||||
Bugs
|
||||
Bug #912919
|
||||
|
||||
Reported by Thomas Caswell on 2012-01-06
|
||||
2 out of 4 heat flames
|
||||
This bug affects 1 person
|
||||
Affects Status Importance Assigned to Milestone
|
||||
python-mode.el
|
||||
Incomplete
|
||||
|
||||
Medium
|
||||
Andreas Roehler
|
||||
python-mode.el 6.0.5 "hill"
|
||||
Also affects project Also affects distribution Nominate for series
|
||||
Bug Description
|
||||
|
||||
Changing py-mode-map to python-mode-map broke ipython. I have added a hacky fix to their tracking.
|
||||
|
||||
https://github.com/ipython/ipython/pull/1242
|
||||
Tags: ipython
|
||||
|
||||
Andreas Roehler (a-roehler) wrote on 2012-01-07: Re: [Bug 912919] [NEW] rev 752 breaks ipython #1
|
||||
|
||||
Am 06.01.2012 21:57, schrieb Thomas Caswell:
|
||||
> Public bug reported:
|
||||
>
|
||||
> Changing py-mode-map to python-mode-map broke ipython. I have added a
|
||||
> hacky fix to their tracking.
|
||||
>
|
||||
> https://github.com/ipython/ipython/pull/1242
|
||||
>
|
||||
|
||||
Hi,
|
||||
|
||||
need some recipe to reproduce.
|
||||
Completion in IPython works fine here with TAB.
|
||||
|
||||
Did you patch against current trunk?
|
||||
|
||||
BTW have a look at
|
||||
|
||||
defcustom py-complete-function
|
||||
|
||||
thanks,
|
||||
|
||||
Andreas
|
||||
Andreas Roehler (a-roehler) on 2012-01-07
|
||||
Changed in python-mode:
|
||||
importance: Low → Medium
|
||||
status: New → Incomplete
|
||||
assignee: nobody → Andreas Roehler (a-roehler)
|
||||
milestone: none → 6.0.5
|
||||
|
||||
|
||||
https://github.com/ipython/ipython/pull/1242
|
||||
|
||||
===== changed key map name to match changes to python mode =====
|
||||
|
||||
This is a minor change to handling the python-mode key mappings. In reversion 752
|
||||
( http://bazaar.launchpad.net/~python-mode-devs/python-mode/python-mode/revision/752 ) the name of the map was changed from py-mode-map to python-mode-map.
|
||||
|
||||
This isn't in any distributions yet, so I am not sure how you want to deal with this.
|
||||
16
Zim/Utils/emacs/Emacs_的_Change_Log_功能.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-19T18:26:43+08:00
|
||||
|
||||
====== Emacs 的 Change Log 功能 ======
|
||||
Created Friday 19 August 2011
|
||||
很多时候,我们的程序目录里并没有像样的版本管理功能(比如自己的一些小工具),过了一段时间,你很可能会发现你不记得以前修改了一些什么、已经实现了哪些功能,甚至于,你都忘记了你的代码里还有啥小 Bug 没处理掉。
|
||||
|
||||
Emacs 自带了一个快速日志记录功能,即 Change Log 的功能。一个 Change Log 文件按时间顺序记录了你修改程序的时间、原因,以及一些你想写下来备忘的内容。当然,Emacs 只会自动帮我们生成记录的时间、修改的文件名,其它的内容还是需要我们自己来补充。
|
||||
|
||||
默认情况下,Emacs 会用当前目录下名为 ChangeLog 的文件来记录这些 log 信息,该文件可以记录该目录以及所有子目录的日志。
|
||||
|
||||
用快捷键 C-x 4 a 或是命令 M-x add-change-log-entry-other-window 就可以为当前编辑的文件在 ChangeLog 文件里添加一条日志,Emacs 会自动创建时间戳和文件名,剩下的内容我们自己补全。
|
||||
|
||||
类似于其他 Emacs 提供的功能,我们可以根据自己的喜好来设置参数,详情看 Chang Log 的官方文档。
|
||||
|
||||
7
Zim/Utils/emacs/Emacs_编辑环境.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-14T21:08:00+08:00
|
||||
|
||||
====== Emacs 编辑环境 ======
|
||||
Created Thursday 14 April 2011
|
||||
|
||||
361
Zim/Utils/emacs/Emacs_编辑环境/1基础部分.txt
Normal file
@@ -0,0 +1,361 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-14T21:08:52+08:00
|
||||
|
||||
====== 1基础部分 ======
|
||||
Created Thursday 14 April 2011
|
||||
|
||||
===== 介绍 Emacs 的编辑环境 =====
|
||||
|
||||
您首先应当知道的是,在 UNIX 中最流行的两种编辑器是 Emacs 和 vi,两者都有超过 30 年的历史。不过,它们都是很难过时的工具。和 UNIX 一样,这些编辑器的基本设计已有几十年之久,但是在最先进的开发中,它们仍然得到了广泛的应用。
|
||||
|
||||
Emacs 是历史上最早的开放源代码和免费软件工程之一。它的发明者 Richard Stallman 建立了 GNU 工程及其父组织—自由软件基金会(请参阅参考资料)。甚至在 Stallman 发布 GNU 公共许可(GNU GPL,一种许可条款,如今的大多数开放源代码软件都是在该条款下发布的)之前,他就已经在类似的免费 copyleft 软件许可(被称为 EMACS 公共许可)下发布了 Emacs 的源代码。
|
||||
|
||||
Emacs 这个名字已经成为专有名词,但它最初是一个首字母缩写词,代表 Editing MACros;Stallman 最初实现的是用 TECO 语言写成的一组宏。Emacs 现在是用 Emacs Lisp 编写的,后者是一种优雅的高级编程语言。
|
||||
|
||||
GNU 工程的简要介绍中称 Emacs 是一种自身配备了相关说明文档的可扩展文本编辑器 (the extensible self-documenting text editor)。Emacs 是可扩展的,这意味着可以在已有功能的基础上添加或构建新功能。之所以有这种可能,是因为它是用 Lisp 编写的,您可以编写新的 Emacs Lisp 例程以添加新功能。您甚至能在 Emacs 会话还在运行时运行这些新功能。它自身配备了相关说明文档,因为每个按键都有相应的即时帮助,即使在键入一个命令时也能显示帮助信息。这样,您可以单击 Help 按钮,弹出各种可能情况的列表。
|
||||
|
||||
Emacs 被称为一个编辑环境,因为它不仅仅是一个普通意义上的、用于纯文本编辑的编辑器。许多管理员和开发人员在各种平台上用它来编译和调试程序、管理电子邮件、在系统中操作文件、运行 shell 命令,以及完成很多其他工作。人们甚至用它在 Usenet 新闻组中进行交流,还用它来浏览网页。扩展包和内置插件可以处理从 Internet 中继聊天 (Internet Relay Chate, IRC) 和发送消息到网络通信的各种情况。一个流传很久的 UNIX 笑话是这样说的:“如果 Emacs 环境里有一个好的编辑器的话,它就不至于这么糟糕了。”
|
||||
|
||||
因为很多任务都可以用 Emacs 来完成,所以它也有自己的词汇表,当您在这一部分中深入了解典型的 Emacs 窗口时,您将学到这些词汇。这一部分还介绍了如何启动和停止 Emacs,以及如何键入各种命令。
|
||||
启动 Emacs
|
||||
要从 shell 中启动 Emacs,键入:
|
||||
__emacs__
|
||||
如果您在控制台或终端中启动 Emacs,您会看到它打开后充满了整个终端窗口,如图 1 所示。
|
||||
|
||||
如果您是在 X 客户端,Emacs 一般会在属于它自己的窗口中打开,如图 2 所示。您还可以指定让它在某个终端窗口打开(如图 1 所示),方法是使用__ -nw __选项。乍一看,Emacs 的这两个视图似乎是不同的应用程序,但两者只有表面的差别。它们仅有的真正不同之处在于缺省的颜色、X 客户端显示的图形徽标,以及 X 客户端顶部附近的图标组(包含某些最常用命令的快捷方式)。两者的文本功能和 X 版本是一模一样的。
|
||||
|
||||
===== Emacs 窗口剖析 =====
|
||||
|
||||
这个屏幕的有些部分需要现在就解释一下。我们从顶部开始,向下介绍。
|
||||
|
||||
==== 菜单栏 ====
|
||||
|
||||
在 Emacs 屏幕顶部是一个突出显示的条,上面有一些单词。这被称为菜单栏,您可以在菜单中选择常用的 Emacs 命令。您能用键盘访问这些菜单;在 X 客户端中,您还可以用鼠标展开菜单。专家们通常会配置他们的 Emacs,使它关闭菜单栏,好在屏幕上留出更大的编辑空间。但是在您学习 Emacs 时,菜单栏是帮您熟悉其丰富功能的好方法。此外,如果您在 X 中打开了 Emacs,您会看到顶部有一组特殊的图标(请参见图 2);它们是某些最常用的菜单选项的快捷方式。要用键盘访问菜单栏,请按__ F10__。现在就试试,看看终端中是如何打开一个新的窗口并显示菜单列表的,如图 3 所示。
|
||||
|
||||
==== 从 Emacs 菜单栏中进行选择 ====
|
||||
|
||||
您可以使用向上或向下的**方向键**,在菜单选项中移动,然后按 Enter。如果您选择的项目有一个子菜单,它会显示在屏幕上。您可以用同样的方法在新的子菜单中选择一个项目,直到您选中了要运行的命令为止。如果您想终止这一过程,可以随时按下 Ctrl-G。这个特殊的键盘输入会使计算机发出一声蜂鸣声,并退出当前正在执行的任何命令。如果没有正在执行的命令,按下这个键盘输入只会使计算机发出蜂鸣声。请现在尝试一下。
|
||||
|
||||
===== 窗口 =====
|
||||
|
||||
屏幕中央大片的主要区域被称为 Emacs 窗口,它是您进行编辑工作的地方。当您打开一个要编辑的文件时,这里将显示该文件的内容。当文件或文档中的内容显示在 Emacs 窗口中时,它被称为**缓冲区**。您可以随时在 Emacs 中同时打开多个缓冲区(即使它们不会显示在主窗口中也一样)。在编辑会话中,虽然只有一个缓冲区会显示在窗口中,但您一般仍会打开多个缓冲区。在 X 客户端中,在窗口的左边会显示一个滚动条。(终端的版本也会出现,但它仅在打开某个缓冲区时显示。)滚动条显示 Emacs 窗口中的文本与缓冲区剩余部分的位置关系与大小关系。
|
||||
|
||||
===== 模式行 =====
|
||||
|
||||
在每个 Emacs 窗口中都有一条横贯底部的高亮条,它被称为模式行,您可以把它看成是状态栏。它将为您提供有关** Emacs 会话和当前缓冲区**(在上面的窗口中显示)的信息,包括您做出的最新修改是否已被保存到磁盘、光标所在行的行号、屏幕底部显示的内容在缓冲区中的位置(用占总体的百分比表示),以及当前有哪些 Emacs 功能和设置处于活动状态。
|
||||
|
||||
===== 迷您缓冲区 (minibuffer) =====
|
||||
|
||||
在模式行下面和屏幕(或 X 客户端窗口)底部的一片小空间被称为迷您缓冲区 (minibuffer)。这是 Emacs 用来显示与操作相关的消息的地方。当 Emacs 要求您输入某种内容(如某文件的名称)时,将在此处显示。与 UNIX shell 类似,迷您缓冲区使用制表符作为提示符。按下 **Tab **键,可获得一个可能情况的列表。另外在minibuffer中输入信息时可以用M-p M-n 以及常用的移动删除命令。
|
||||
|
||||
|
||||
===== Emacs 的键绑定 =====
|
||||
|
||||
一**个用来调用特定命令的 Emacs 组合键被称为一个键绑定**。这些都可以自定义,但 Emacs 也附有缺省的绑定。
|
||||
|
||||
一眼看去,为数众多的 Emacs 键绑定似乎很复杂,让人不知所措,不过请务必记住,它们是为了提高您的速度和便于记忆而专门设计的。通常每个绑定都有一个记忆的方法,如 S 键就是用来保存 (save) 的。在您尝试使用它们时,请想想这一点。__总的说来,Emacs 命令可分为两大类:一类要使用 Ctrl 键,而另一类使用 Meta 键。__
|
||||
|
||||
===== Ctrl 组合键 =====
|
||||
|
||||
许多 Emacs 命令是由某个 Ctrl 组合键指定的。.在 Emacs 的符号中,Ctrl 键写成“C-”,后面则是与第二个按键对应的字符。例如,在 Emacs 符号中,Ctrl-X 组合键写成 C-x。要输入一个 Ctrl 组合键,请按住 Ctrl 键,然后按第二个键,然后将两个键同时松开。大多数命令都有一个 Ctrl 组合键,在按下此组合键后要再输入一个单词或第二个 Ctrl 组合键。例如,可以尝试运行 C-x C-s 命令,将当前的缓冲区保存到磁盘。因为您没有作出更改,所以也无需进行保存,但这个组合键值得一试。现在,请尝试进行以下操作:
|
||||
|
||||
按住 Ctrl 键。
|
||||
按 X 键,然后把两个键同时松开。
|
||||
再按住 Ctrl 键。
|
||||
按 S 键,然后把两个键同时松开。
|
||||
|
||||
这个键盘输入将运行 save-buffer 命令。在迷您缓冲区中,Emacs 会报告“(No changes need to be saved)”。
|
||||
|
||||
Emacs 用户在按这些组合键时,**在第二个步骤中往往不会松开 Ctrl 键,这样可以省去第三个步骤**,加快键入速度。请尝试一下。
|
||||
|
||||
===== Meta 组合键 =====
|
||||
|
||||
Emacs 键盘输入中的第二种主要类型是 Meta 键;在 Emacs 符号中,Meta 按键被表示为 M-。如果您从未听说过 Meta 键,那是因为目前的大多系统并没有这个键。输入 Meta 组合键,有三种方法:
|
||||
|
||||
Meta 键常被绑定到 Alt 键,使用方法与 Ctrl 键类似。如果您的设置就是这样,请使用该设置,这是最简单、最常见的方法。
|
||||
通常您可以使用 Esc 键完成一个 Meta 按键序列,但您的操作与输入一个 Ctrl 按键序列时不同。按下 Esc,然后松开,再按第二个键。
|
||||
您可以用 Ctrl-[ 代替 Esc 键。如果您通过网络线路运行 Emacs,无法使用 Esc 和 Alt 键,这种方法会很方便。
|
||||
|
||||
请尝试输入 M-b 命令,这会把光标向回移动一个单词,有三种操作方法:
|
||||
|
||||
按住 Alt 键,然后按一下 B。
|
||||
按下 Esc,然后松开,再按一下 B。
|
||||
按住 Ctrl 键,再按 [,同时松开两个键,然后再按一下 B。
|
||||
|
||||
您运行的**每个 Emacs 命令都是一个函数,由 Emacs Lisp 定义,并有一个函数名**。甚至连用向上方向键将光标向上移动一行也是一个函数(previous-line)。您可以使用 M-x 命令,然后再输入函数名,运行任意一个函数。
|
||||
|
||||
请尝试以下操作:
|
||||
|
||||
按住 Alt 键。
|
||||
按 X 键。
|
||||
同时松开两个键,您会注意到迷您缓冲区中会出现“M-x”字样。
|
||||
键入 previous-line 并按 Enter。
|
||||
|
||||
当您这样操作时,光标会向上移动一行。当然,您平常是不会这样运行这个函数的,因为使用向上方向键比这容易多了,不过这是个好例子。函数为数众多,而且由于 Emacs 是可扩展的,您可以编写自己的函数以扩展其功能。
|
||||
|
||||
与通过向上方向键运行 previous-line 类似的是,**许多函数都分配了快捷键。当您输入这样的一个键或组合键时,将运行相应的函数**。您还可以使用 C-p 运行 previous-line 函数。现在,请尝试下面的操作:
|
||||
|
||||
按住 Ctrl。
|
||||
按 P 键。
|
||||
再按方向键,将光标移到窗口的顶部。
|
||||
|
||||
作为总结,表 1 列出了您可以在 Emacs 键绑定中使用的主要按键前缀类型。和 Emacs 中的其他东西一样,这些都是可以自定义和重新定义的。
|
||||
|
||||
__表 1. 常用的缺省 Emacs 按键前缀__
|
||||
按键前缀 描述
|
||||
C-c 当前**编辑模式特有**的命令
|
||||
C-x 文件和缓冲区命令
|
||||
C-h 帮助命令
|
||||
M-x 函数名称
|
||||
|
||||
===== 停止 Emacs =====
|
||||
要退出 Emacs,请键入:
|
||||
|
||||
__C-x C-c__
|
||||
|
||||
如果有未保存的缓冲区,这个命令会使您有机会保存它们。
|
||||
|
||||
这是退出 Emacs 的一般方法。请现在就试着操作一下,然后在 shell 的提示符下键入 emacs,重新启动 Emacs。
|
||||
|
||||
===== 缓冲区和文件 =====
|
||||
|
||||
在这一部分中,将介绍最重要的 Emacs 缓冲区和文件命令:如何将文件载入缓冲区,如何将缓冲区保存到文件,如何在缓冲区间切换,以及如何“杀死”缓冲区。
|
||||
|
||||
|
||||
===== 从头创建一个新文件 =====
|
||||
|
||||
当您用普通的方式启动 Emacs 时,它将向一个名为** scratch **的缓冲区开放,该缓冲区的用途显示在缓冲区顶部的一条消息中:
|
||||
;; This buffer is for notes you don't want to save,
|
||||
and for Lisp evaluation.
|
||||
;; If you want to create a file, visit that file with C-x C-f,
|
||||
;; then enter the text in that file's own buffer.
|
||||
|
||||
模式行左边的区域始终用来显示当前缓冲区的名称。在此处,您可以看到这个缓冲区的名称,即 *scratch*。**如果是 Emacs 自动创建的特殊缓冲区,其名称两边会有星号。**
|
||||
|
||||
试着输入一行文本:This is a practice file. 然后再按 Enter,将光标向下移到一个新行。当您开始输入时,您会看到**模式行的左侧出现两个星号,这表明当前的缓冲区中有未保存到磁盘的文本。**
|
||||
|
||||
创建新文件的方法之一是将 scratch 缓冲区写到某个文件中。组合键 __C-x C-s 会运行 save-buffer__ 命令,将当前的缓冲区保存到某个文件。正如您先前看到的,当您在一个无需保存的缓冲区中运行此命令时,Emacs 会显示相应的信息。但如果在您运行该命令的缓冲区中有未保存的更改,且该缓冲区与磁盘上的某个特定文件相关联时,缓冲区的内容会被写入该文件。如果您是在新缓冲区或某个没有与文件关联的缓冲区(例如您现在所在的 scratch 缓冲区)中运行该命令,Emacs 将提示您指定用来保存该缓冲区的文件名称。
|
||||
现在,请尝试下面的操作:键入 Ctrl-x Ctrl-s。看看在迷您缓冲区中是如何要求您给出要保存的文件名称的,如图 4 所示。现在键入 practice。
|
||||
在您按下 Enter 后,Emacs 会在迷您缓冲区中报告,有一个名为 practice 的新文件已被写入磁盘。键入 C-x C-c,退出 Emacs,然后查看目录,找到您的文件:
|
||||
关于 scratch 缓冲区,还有一件事是需要记住的。**如果 Emacs 中没有打开其他缓冲区,那么 scratch 缓冲区会一直存在,当它是打开的唯一缓冲区时,是无法被关闭的。**
|
||||
|
||||
===== 利用文件名启动 Emacs =====
|
||||
|
||||
要使 Emacs 启动时将某个特定的文件的内容放进一个新的缓冲区中以便编辑,请提供此文件的名称作为参数。如果您提供了多个文件,则每个文件会在属于它自己的缓冲区中打开。**如果您提供的文件名在磁盘上不存在,Emacs 会为该文件创建一个新的缓冲区**,并说明(在模式行中)这是一个新文件。这是您在启动 Emacs 并编辑一个新文件时所做的。当您将缓冲区保存到磁盘时,Emacs 将其写入文件,并使用您提供的参数做为它的文件名。
|
||||
请试着用您的文件“practice”启动 Emacs:
|
||||
您仍会看到 Emacs 的欢迎屏幕,但如果您按下一个键,如 C-g(或等足够长的时间),您会在 Emacs 窗口中看到您文件。没错,欢迎屏幕是另一个可供配置的选项。
|
||||
|
||||
===== 打开一个文件 =====
|
||||
Emacs 不会对文件的内容进行直接操作。它会把文件内容的副本读取到您编辑的缓冲区中。使用 __C-x C-f,即 find-file 命令__,以便用文件的内容打开一个缓冲区。
|
||||
|
||||
===== 访问缓冲区 =====
|
||||
|
||||
C-x b 命令可以从当前缓冲区切换到您指定的另一个缓冲区。迷您缓冲区中始终会提供一个缺省的缓冲区选项。如果您按下 Enter 且没有指定缓冲区的名称,您会切换到上述的缓冲区。**缺省值一般是您上次访问的缓冲区**。如果您之前没有访问任何缓冲区,则缺省值通常为 scratch 缓冲区。
|
||||
现在键入 C-x b,注意 scratch 缓冲区会作为建议项显示在迷您缓冲区中。键入 Enter,您的 practice 文件将从窗口中消失,代之以您熟悉的 scratch 缓冲区中的内容。(在缺省情况下,scratch 缓冲区会包含三行消息,但有时该缓冲区为空白。)再次键入 C-x b,然后按 Enter,切换回 practice 缓冲区。
|
||||
在 Emacs 中,如果您希望创建一个新的缓冲区,请切换到您要指定名称的那个缓冲区。
|
||||
再次键入 C-x b,不过要将该缓冲区命名为 mybuffer。注意,窗口是空的,这是一个全新的缓冲区。键入一行文本,然后按 Enter:
|
||||
On what wings dare we aspire?
|
||||
|
||||
键入 C-xC-s,将这个缓冲区保存到磁盘。注意,现在 Emacs 会要求您指定一个文件名。__如果您创建的新缓冲区没有与磁盘上的某个文件关联,您可以在决定保存它时指定一个文件名。您指定的文件名不必与缓冲区名称相同,可以把它命名为 practice.b,请注意,Emacs 会改变缓冲区的名称,使之与新文件相符。__
|
||||
|
||||
===== 杀死缓冲区 =====
|
||||
|
||||
请使用 C-x C-k 命令杀死某个缓冲区,或将其排除在您的 Emacs 会话之外。您将被提示键入要杀死的缓冲区的名称,**当前的缓冲区是缺省缓冲区**,如果您直接按下 Enter,会将它杀死。
|
||||
现在试着杀死旧的 practice 缓冲区:键入__ C-x C-k__,然后当 Emacs 在迷您缓冲区中要求输入一个缓冲区名称时,键入 practice,然后按 Enter。practice 缓冲区会被杀死,而 practice.b 缓冲区则像刚才一样留在窗口中。
|
||||
|
||||
===== 将缓冲区保存到磁盘 =====
|
||||
|
||||
您已经知道了如何通过运行 **C-x C-s save-buffer 命令**,将缓冲区的内容保存到磁盘。您需要了解这一过程的更多信息。
|
||||
|
||||
模式行的前几个字符描述了缓冲区的状态。现在,在您的 practice.b 缓冲区中键入另一行文本,然后按 Enter:
|
||||
|
||||
What the hand dare seize the fire?
|
||||
|
||||
|
||||
注意,模式行中的两个破折号会变成两个星号。**破折号说明缓冲区的内容与磁盘中的相同,而星号则表示缓冲区中有未保存的编辑内容**。
|
||||
|
||||
保存更改并退出 Emacs:键入 C-x C-s C-x C-c。您的目录中会多出几个新文件:
|
||||
$ ls
|
||||
practice
|
||||
practice.b
|
||||
practice.b~
|
||||
|
||||
practice 和 practice.b 文件是您创建的,但 practice.b~ 则是一个由 Emacs 自动创建的文件。这是 Emacs 的备份文件,当您每次在 Emacs 中编辑一个已经存在的文件时都会创建这个备份文件。当**您将编辑内容保存到文件时,Emacs 会写到一个新文件中以制作备份(此编辑会话第一次保存该文件时创建)**,这个新文件的名称与原先的文件相同,只是多了一个波浪符号。旧的 practice 文件没有备份,因为您在创建它之后从未对其进行编辑。如果您此后在 Emacs 中编辑了它,Emacs 会将内容写入相应的 practice~ 备份文件。
|
||||
|
||||
Emacs 还会写入另一种文件,被称为 autosave 文件,它与原先的文件名称相同,但是在名称前后会各添加一个英镑符号。在您操作缓冲区期间,Emacs 会按设置的间隔向 autosave 文件写入内容。在缺省情况下是每输入 300 个新字符就向 autosave 文件写入一次。通常,**在您杀死缓冲区时是不会见到 autosave 文件的。**这是因为与缓冲区关联的 autosave 文件被删除了。如果您的系统崩溃,或您在编辑会话中失去连接,autosave 文件很有用,它为您提供了一个选择,使您可以在目录下找到这个文件以恢复丢失的编辑内容。
|
||||
|
||||
__缓冲区和文件命令总结__
|
||||
|
||||
表 2 包含的是某些最常用的缓冲区和文件命令列表,在您学习 Emacs 的过程中将用到这些命令。该表提供了命令绑定的键盘输入和命令的函数名。请记住,**您总能使用相应的键绑定,或将相应的函数名作为 M-x 的参数,以运行某个命令**(请参考学习如何键入 Meta 组合键)。
|
||||
绑定 函数名 描述
|
||||
C-x C-s save-buffer 将当前的缓冲区保存到磁盘。
|
||||
C-x s save-some-buffers 要求将所有未保存的缓冲区保存到磁盘。
|
||||
C-x C-c save-buffers-kill-emacs 要求将所有未保存的缓冲区保存到磁盘,并退出 Emacs。
|
||||
C-x C-z suspend-emacs 挂起 Emacs 并使之成为一个后台进程。
|
||||
C-x C-b list-buffers 列出所有缓冲区。
|
||||
C-x k kill-buffer 杀死一个缓冲区(缺省情况下为当前的缓冲区)。
|
||||
C-x C-q vc-toggle-read-only 切换当前缓冲区的可读状态(如果适用还可以执行版本控制)。
|
||||
C-x d 打开目录
|
||||
C-x i insert-file 在插入点插入某个文件的内容。
|
||||
|
||||
===== 在 Emacs 中编辑文本 =====
|
||||
|
||||
在缓冲区中输入和更改文本,以及在文本中进行导航,是您在 Emacs 中最重要的操作,无论您是在编辑文件,创建新文件,还是仅仅想研读某个文件,都要用到它们。在此部分,您将学习用来完成下述工作的基本按键序列和命令:如何在缓冲区中输入文本,如何在文本中导航,以及如何对文本进行基本的编辑,如删除字符和单词。
|
||||
|
||||
==== 键入文本和在缓冲区中移动 ====
|
||||
|
||||
正如您在从头创建一个新文件这一部分看到的,在 Emacs 缓冲区中输入文本是很容易的,您只要动手打字就行。您可以键入字母字符,将其输入某个缓冲区中。Emacs 有时会被称为**无模式编辑器**,常被拿来与模式编辑器如 vi 等作比较。这意味着编辑器的行为以及您可以键入的键盘输入和命令在您的会话中是保持不变的,与 vi 等编辑器不同,后者的击键会根据您是在命令模式还是在输入模式而有不同的含义。Emacs 没有这类模式;不过,它确实有一种不同的模式,可以用来更改其行为或扩展其功能,这将是本系列的下一篇教程的主题。进行普通的输入时,有些事是您必须记住的。
|
||||
|
||||
==== 在插入点插入文本 ====
|
||||
|
||||
在 Emacs,有一个重要的概念,被称为__插入点point,它表示字符的插入位置。这是缓冲区中一个想像的位置,处于光标所在字符和前一个字符之间。__
|
||||
|
||||
每当您在缓冲区中输入文本时,该文本都会在这个点插入。**在缺省情况下,所有文本都在同一**行,在这个点之后的文本会向右推移,为您插入的内容让出空间。按 Enter,移到下一行,然后再按一下 Enter,插入一个空白行。
|
||||
在每一行的末尾按 Enter,以输入一个段落,然后在结尾再按一下 Enter,创建一个空白行。
|
||||
|
||||
===== 移动插入点 =====
|
||||
|
||||
您会看到,在您键入时光标会一直跟随,**插入点保持不变**:从您键入第一个句子开始,您键入的一切内容都被插入字母 O 之前。要移动插入点,您可以使用方向键,而且正如您预期的那样,所有其他与光标动作有关的键都可供使用,如 PgUp、PgDn、Home 和 End。但 Emacs 自带用来移动光标的键绑定,而且因为您不必将手移到键盘的基准键之外就能使用它们,所以您在打字时会觉得它们非常有用。
|
||||
正如您在学习如何键入 Meta 组合键部分中看到的,您可以使用 C-p 将标向上移动到上一行;类似地,C-n 将光标向下移动到下一行。C-f 会向前移动到下一个字符,而 C-b 会向后移动到上一个字符。
|
||||
如果不想用 PgDn 和 PgUp 键向上和向下移动一屏,请使用 C-v 和 M-v 这两种键盘输入,它们可起到与前两个键相同的作用。要转至当前行的开始处,请使用 C-a;使用 C-e,转到当前行的结尾。
|
||||
通常 Meta 键会被绑定到某个命令,这与相应的 Ctrl 键类似,对于移动命令,这条规则也同样适用。当使用 Meta 来代替 Ctrl 时,F 和 B 键可以向前和向后移动一个单词 而不是一个字符,而 A 和 E 键可以移动到当前句子的开头和结尾。(在缺省配置中,没有定义 M-n 和 M-p 键盘输入。)
|
||||
表 3 列出了各种移动和导航的键,以及它们的函数名和描述。试着用它们移动到缓冲区的开头、结尾,和中间的某些位置。
|
||||
|
||||
__表 3. 有用的 Emacs 键盘输入(用于移动和导航)__
|
||||
键盘输入 函数 描述
|
||||
C-p,
|
||||
UpArrow previous-line 将插入点向上移动到上一行。
|
||||
C-n, DownArrow next-line 将插入点向下移动到下一行。
|
||||
C-f, RightArrow forward-char 将插入点移动到下一个字符。
|
||||
C-b, LeftArrow back-char 将插入点移动到上一个字符。
|
||||
M-f forward-word 将插入点移动到下一个单词。
|
||||
M-b backward-word 将插入点移动到上一个单词。
|
||||
C-v, PgDn scroll-up 将文本向上滚动一屏。
|
||||
M-v, PgUp scroll-down 将文本向下滚动一屏。
|
||||
Home beginning-of-buffer 将插入点移到缓冲区的开始处。(在某些版本中,这个键被缺省定义为移动到当前行的开始处。)
|
||||
M-< 同上
|
||||
End end-of-buffer 将插入点移到缓冲区的末尾。(在某些版本中,这个键被缺省定义为移动到当前行的末尾。)
|
||||
M-> 同上
|
||||
C-a beginning-of-line 将插入点移到本行的开始处。
|
||||
C-e end-of-line 将插入点移到本行的结尾。
|
||||
M-a beginning-of-sentence 将插入点移到句子的开始处。
|
||||
M-e end-of-sentence 将插入点移到句子的结尾处。
|
||||
C-{ beginning-of-paragraph 将插入点移到段落的开始处。
|
||||
C-} end-of-paragraph 将插入点移到段落的结尾处。
|
||||
|
||||
===== 使用改写模式 =====
|
||||
|
||||
正如您看到的,您键入的文本被插入到插入点处。不过您也可以改写现有的文本。按一下 Ins 键;这将切换到改写模式,该模式在缺省情况下是关闭的。查看模式行,您会看到__ Ovwrt__,说明该模式已处于活动状态。用表 3 中描述的移动命令,移动光标,使之处于 we 中的 w 处,然后键入一个 h 字符。
|
||||
请试着转至缓冲区的顶部:键入 M-a M-a C-f,将光标移到 y,然后输入一个 i 字符。对于下一个 y,采取同样的操作,键入 M-f C-f C-f C-f i,以使缓冲区看起来如图 6 所示。
|
||||
|
||||
===== 引用插入 =====
|
||||
|
||||
文本并不仅限于用字母键输入。您可以输入控制字符,也可以根据字符代码输入字符。为此您可以执行**引用插入,该命令被绑定到 C-q**;此后再按一个键(或组合键)如 Ctrl 组合键,以便在插入点输入该键。您还可以输入一个字符代码值(用八进制表示),然后再按 Enter 键。
|
||||
移到缓冲区的末尾,键入 Page break here,然后按 Enter。现在键入一个分页符,即 Ctrl-l 代表的字符,在它的后面接一个转义字符,该转义字符的八进制字符值为 033: C-q C-l C-q 033 Enter.
|
||||
|
||||
===== 删除,撤消和重复 =====
|
||||
|
||||
现在您可以试试 Emacs 中的一些工具,这些工具用来处理现有文本以及撤消(和重复)您已经做出的操作。
|
||||
|
||||
===== 删除文本 =====
|
||||
|
||||
**使用 Backspace 或 Del 键(不是Delete键),删除插入点左边的字符。**试着用这两个键删除您刚才输入的两个控制字符。
|
||||
要删除**插入点右边即光标上**的字符,请用 C-d;类似地,M-d 会**从插入点**开始,删除到单词的末尾。您还可以向回删除,**M-Del 和 M-Backspace 都可以从插入点一直删除到单词的开头。或用**__M--反向操作符__**如:**
|
||||
M-- C-d 反向删除一个字符
|
||||
M-- M-d 反向删除一个单词
|
||||
|
||||
|
||||
将光标移动到文件的最后一行(应该是“What the hand dare seize the fire?”这个句子),然后按几次 M-d,把这一行删除。
|
||||
|
||||
===== 撤消和重复 =====
|
||||
|
||||
啊呀,如果您并不想删除最后一句怎么办?您可以通过运行 undo 函数把它找回来。该函数被绑定到 __C-___,您要键入它,请按住 Ctrl,并用 Shift 键输入下划线。请回到最后一行试试,每个单词操作一次,找回这些单词。
|
||||
多操作几遍,直到 Page break here 重新显示为止。
|
||||
现在您又对上次的撤消操作感到后悔了,您确实不想要 Page break here 了。您可以重复您撤消的操作,方法是键入 C-g,这将取消所有的撤消操作,然后多次键入 C-_ 使单词再次消失。
|
||||
|
||||
===== 多次运行同一个命令 =====
|
||||
|
||||
__C-u 是一个通用参数命令(但还有其它含义如)__,后面接一个数字和一个命令。它将按某个次数多次运行特定的命令。
|
||||
尝试以下操作:移动到第二句诗的开始处,键入 In what distant d,然后再键入 C-u 2 e,这将写入两个 e 字符。输入以下内容,完成诗句:
|
||||
|
||||
ps or skies
|
||||
Built the fire of thine eyes?
|
||||
|
||||
===== 使用通用参数插入字符 =====
|
||||
|
||||
在**没有数字参数的情况下,C-u 会假定这个数字为 4**。如果您将 C-u 本身作为参数,则 4 会自乘,得到 16;您可以在反复自乘任意多次之后再指定一个命令,如 C-u C-u C-u A 会在插入点处键入 64 个 A。
|
||||
请用一个 C-b,向回移动,您会看到光标会回到前面的一行。现在试试通用参数,键入 C-u C-b;注意光标向回移动了四个字符(而不是一个)。再试试 C-u C-u C-b,注意光标会向左移动 16 个字符。键入 C-u C-u C-u C-b,然后再指定 1000 作为参数:C-u 1000 C-b。光标会移动到缓冲区的开始处,但请注意,Emacs 会发出蜂鸣声,这表明它在完成要求的操作次数之前就已经到了缓冲区的顶部(无法再向回移动了)。
|
||||
我们来总结一下刚才学到了什么。在您继续学习下一部分之前,请看看表 4,它列出了重要的编辑命令和执行这些命令时用的缺省键盘输入。
|
||||
|
||||
__表 4. 常用 Emacs 编辑命令__
|
||||
键盘输入 函数 描述
|
||||
Ins overwrite-mode 切换改写模式(缺省为关闭)。
|
||||
Backspace
|
||||
Del delete-backward-char 删除插入点前的字符。
|
||||
C-d delete-char 删除插入点处的字符。
|
||||
M-d kill-word 从插入点开始向前删除字符,直到单词末尾。
|
||||
M-Backspace,
|
||||
M-Del backward-kill-word 从插入点开始向回删除字符,直至单词的开始处。
|
||||
C-_ undo 撤消您的上一次键入或操作
|
||||
C-q 字符 或 XXX quoted-insert 在插入点插入按键本身代表的字符或由八进制数字(XXX)表示的字符。
|
||||
C-u 次数 命令 universal-argument 按总的次数(缺省为 4 次)连续执行命令。
|
||||
M- 次数 命令 digit-argument 同上
|
||||
|
||||
===== 标记和鼠标 =====
|
||||
|
||||
您正在顺利地学习关于 Emacs 编辑的所有基本知识,但还有一些重要的概念是您需要知道的:如何标记文本区域并在这些区域上执行操作,以及如何使用鼠标。
|
||||
|
||||
==== 标记、移除、删除 ====
|
||||
|
||||
Emacs 有一项标记文本区域的功能,您可以将这个**区域作为一个整体进行编辑**:表 5 中对这些命令进行了描述和简要介绍。
|
||||
|
||||
|
||||
==== 标记一个区域 ====
|
||||
|
||||
移动到缓冲区的顶部,即诗的第一节的开始处,然后键入** C-Space**,或**C-@**,方法是按住 Ctrl,再按空格键。这被称为**设置标记**;迷您缓冲区中会出现一条消息,告诉您已经设置了标记。
|
||||
|
||||
**插入点和您设置标记的位置(包括标记处的字符)之前的部分被称为区域。**
|
||||
|
||||
将插入点由开始处移动到小节后的空白处,将整个第一小节设置为区域
|
||||
|
||||
===== 删除和恢复文本 =====
|
||||
|
||||
有些特殊的命令可用来操作区域,包括 C-w,它能删除区域。
|
||||
键入 C-w,删除您刚才定义的区域。
|
||||
|
||||
每次您删除文本时,这些文本都会保存在 Emacs 的__ kill ring__ 中。您可以用 C-y 把它们恢复到插入点。移动到缓冲区的末尾,按 Enter,插入另一个空白行,然后将这个小节移回去。
|
||||
您不仅能删除区域;使用 C-k 还可以删除从插入点到行末的所有文本。向上移到以 Tiger 开头的一行,然后用 C-k 删除它。注意,这一操作不会删除空白行;还要第二次使用 C-k。按此操作,然后使用 C-y 将整行移回去。如果您用多个删除命令连续进行删除,它们会叠加在一起,只返回一个移除内容。
|
||||
您可以将某一行恢复任意多次。移动到缓冲区的顶部,然后再次使用 C-y 把它移回去。
|
||||
您还可连续多次使用 C-k 键盘输入进行删除,删除的内容会被移到一起。请试试一次删除多行,然后使用 C-y 将它们移回原先的位置。
|
||||
|
||||
|
||||
===== 复制文本 =====
|
||||
如果您是想复制区域,不必删除它。如果要将区域保存在 kill ring 中而不是删除它,请使用 M-w(而不是 C-w)。
|
||||
|
||||
__表 5. 用来标记和删除文本的 Emacs 函数__
|
||||
键盘输入 函数 描述
|
||||
C-Space set-mark-command 在插入点设置标记。
|
||||
C-k kill-line 删除从插入点到行末的所有文本。
|
||||
C-w kill-region 删除区域。
|
||||
M-w kill-ring-save 将区域保存在 kill ring 中,但不删除它。
|
||||
C-y yank 恢复来自 kill ring 的文本。
|
||||
|
||||
===== 用鼠标进行标记和移动 =====
|
||||
|
||||
虽然 Emacs 是为了用键盘快速操作而设计的,但是您也可以使用鼠标,这对文本操作来说有时是很方便的。
|
||||
要将**插入点移到缓冲区的任意位置**,请把鼠标指针移到该位置,然后单击一下鼠标左键。试着用鼠标移动到诗的第二节和第三节之间的空白处,然后键入新的一节。
|
||||
用**左键**__双击__**一个单词以选中它**。双击您刚刚键入的 Tiger,它将突出显示,然后按 Del 将它删除。现在键入 Lamb,将这个单词插入插入点处。
|
||||
要用**鼠标选择一整行,请用鼠标左键**__三击__该行。请在顶行尝试此操作,然后按 Del 将该行删除。键入 C-_ 恢复删除的内容。
|
||||
在缓冲区的中间单击鼠标左键,然后再输入两段,完成这首诗:
|
||||
|
||||
您可以单击鼠标左键(设置区域的开始标记),然后拖动以选择一个区域,在释放左键前单击一次右键可以将选区内容复制到 kill ring 中,单击两次右键将删除选区。您可以使用 C-y 或鼠标中键将文本复制到插入点处。
|
||||
|
||||
===== 表 6. Emacs 中的鼠标操作 =====
|
||||
鼠标命令 描述
|
||||
B1 这一命令将设置插入点位置;拖动鼠标左键以设置区域。
|
||||
B1-B1 这一命令标记一个单词。
|
||||
B1-B1-B1 这一命令标记一行。
|
||||
B2 这一命令将移除文本。
|
||||
B3 这一命令会设置并突出显示区域,然后无需删除就将其放在 kill 缓冲区中。__如果某个区域已经被突出显示并设置,该区域的末尾将移动到您单击的位置。__
|
||||
B3-B3 这个命令将突出显示区域,然后删除它。如果某个区域已经被突出显示并设置,该区域的末尾将移动到您单击的位置,此后该区域将被删除。
|
||||
105
Zim/Utils/emacs/Emacs_编辑环境/2基本模式和编辑特性.txt
Normal file
@@ -0,0 +1,105 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-14T21:57:03+08:00
|
||||
|
||||
====== 2基本模式和编辑特性 ======
|
||||
Created Thursday 14 April 2011
|
||||
|
||||
|
||||
===== 编辑模式 =====
|
||||
Emacs 被划分为无模式 的编辑器,这意味着它与其他的编辑器(如 vi)有所不同,对于运行编辑器命令或者向缓冲区插入文本的插入模式,没有特殊的命令模式——正如您在本系列前面的教程中所看到的,可以在任何时候完成命令和文本插入。
|
||||
然而,Emacs 也有它自己的编辑模式,这就是**扩展它的能力或者改变一些特性工作方式的函数**。这些模式通常用于编辑某种类型或类别的数据,如常规文档(使用任何印欧语言编写)、用特定的计算机编程语言(C、Fortran、Lisp 等等)编写的源代码、采用某种方式进行格式化(大纲、电子邮件消息、Usenet 文章、基于字符的示例等等)或使用标记语言(超文本标记语言 (HTML)、Nroff、TeX 和可扩展标记语言 (XML))的文本。甚至专门有一种模式用于编辑非文本(二进制)的数据。另外,Emacs 还提供了许多特殊的模式,可用于其他数据类型和系统处理,包括网络连接和网际中继交谈 (IRC)、Shell 会话和 UNIX 文件系统自身。
|
||||
|
||||
这些模式可以划分为**主要模式和次要模式**。**主要模式规定了主要的编辑行为,并且仅应用于当前编辑会话中的缓冲区**。在任何时刻,每个缓冲区都有且仅有一个活动的主要模式。
|
||||
|
||||
尽管在任何时刻,一个缓冲区仅有一个活动的主要模式,但您可以根据需要在主要模式之间进行切换。**一些专门的主要模式还提供了额外的功能和辅助**(如上下文突出显示和颜色设置),当您在编辑某些类型的文档时,这是很有帮助的,但是您无需为编辑某种类型的文件或文档选择特定的模式——可在任何模式中编辑一个 C 程序源代码文件,正如它可在编辑 C 程序语言的特殊模式中完成。
|
||||
|
||||
**次要 模式通常提供了一些与任何特定的主要模式无关的特性或功能**。可以把它们看作用于控制这些特性的切换:使用其函数名来调用一个次要模式可以开启或关闭该模式,任何时候您都可以开启多个次要模式。
|
||||
|
||||
次要模式包括__ Overwrite __模式(本系列文章的第一部分教程对其进行了描述)、用于管理签入版本控制系统 (RCS) 的文件的 __RCS__ 模式、以及处理自动文字回绕的 __Auto Fill __模式。可以在任何时候同时激活所有这些次要模式以及许多其他类似的模式。
|
||||
|
||||
===== 查看哪些模式是活动的 =====
|
||||
|
||||
如本系列文章的第一个教程中所述,靠近 Emacs 窗口底部的突出显示栏,被称为模式行,可以告诉您当前缓冲区的所有情况——包括哪种模式当前是活动的。在模式行右边的括号里注明了当前的模式。__最先列出主要模式的缩写名称,后面是任何次要模式的缩写名称__。
|
||||
|
||||
当您启动 Emacs 编辑器而不打开任何文件时,则处于暂存缓冲区。在缺省情况下,这个缓冲区以 Lisp Interaction 模式打开,这是一个用于计算 Lisp 代码的特殊模式。
|
||||
您可以用通常的方式启动 Emacs,观察模式行里写了些什么。
|
||||
当您改变这些模式的时候,将在模式行里看到其反映出来了模式的改变。现在,请尝试下面的操作:按 Ins 键以打开 Overwrite 模式,并注意模式行的变化。(Ins 键与 overwrite-mode 函数进行了绑定)。
|
||||
再次按 Ins 以关闭 Overwrite 模式。
|
||||
当启用一个次要模式时,通常在括号里会有显示,紧接在主要模式的后面。然而,**并非所有的次要模式都有这种指示器**——有些次要模式是非常明了的(如 Tool Bar 模式),它在 Emacs 框架的顶部显示了图形工具栏。较新版本的 Emacs 中其他的次要模式都非常简单(并且始终处于开启状态),以至于如果要把它们全部显示出来,只会使显示变得非常混乱;例如,次要模式 Unify 8859 On Encoding 的目的是为各种 ISO 8859 字符集提供统一的编码方式,这样有助于进行国际化。
|
||||
另外,一些模式提供了**额外的指示器**,这些指示器也会在模式行里显示出来。例如 Line Number 模式,通过在 L 后面跟上行号来表示,该行号是光标在缓冲区中的当前位置。
|
||||
|
||||
===== 获得当前模式的描述 =====
|
||||
|
||||
可以使用 describe-mode 函数,该函数与 **C-h m** 进行了绑定,用于获得当前模式的描述。当您运行这个函数时,将打开一个新的帮助缓冲区,其中列出了所有的键绑定,这些键绑定是您进行输入的缓冲区的当前主要模式所特有的,后面跟的是应用于任何处于打开状态的次要模式的绑定。
|
||||
|
||||
正如您所看见的,用于 Lisp Interaction 模式的特殊绑定之一是 Tab 键。在这个模式中,Tab 并不会像您希望的那样在打字机或文字处理应用程序中将光标移动到下一个制表位处,而是按照模式描述所说的,它会对当前 Lisp 代码行进行缩进。因为您没有在这个缓冲区中编写任何 Lisp 代码,所以 Tab 什么都不做——您可以试试看。
|
||||
|
||||
===== 缺省模式 =====
|
||||
|
||||
尽管暂存缓冲区通常设置为 Lisp Interaction 模式,但它并不是缺省 Emacs 模式。要找出缺省模式是什么,可以切换到一个新的缓冲区:输入 C-x b 并指定 lamb.txt 作为缓冲区的名称。输入 C-x 1 关闭帮助缓冲区。
|
||||
您将看到这个新的 lamb.txt 缓冲区有了新的主要模式,即 **Fundamental 模式。这就是 Emacs 缓冲区的缺省模式**。在所有 Emacs 模式中,这种模式是最简单明了的,拥有最少的特殊键绑定和设置。在这种模式中,Tab 键将按照您所希望的方式进行工作。
|
||||
|
||||
再次键入 C-h m 继续工作并获取这些模式的描述。
|
||||
|
||||
当您在新的缓冲区中打开现有文件中的内容时,Emacs 将**基于该文件类型**为您选择一种模式。如果您打开的文件包含 C 程序源代码,那么 C 模式将成为主要模式;同样,如果您打开的文件包含口语(如英语)文本,那么 Emacs 会将 Text 模式设置为主要模式。
|
||||
|
||||
您可以不断地改变模式,并且您还可以对所有这些设置进行配置,这样一来,就始终能够以特定的模式打开某种文件或者某种类型的缓冲区。表 1 描述了常用的 Emacs 模式,并给出了它们的函数名。
|
||||
|
||||
===== 表 1. 常用的 Emacs 模式 =====
|
||||
模式 函数 类型 描述
|
||||
Fundamental fundamental-mode 主要模式 这一模式是缺省的 Emacs 模式,拥有最少设置和绑定。
|
||||
Text text-mode 主要模式 这一模式是编辑文本的基本模式。
|
||||
Abbrev abbrev-mode 次要模式 这一模式用于生成和使用缩写请参见 Abbrev 模式)。
|
||||
Auto Fill auto-fill-mode 次要模式 这一模式用于自动文字回绕、填充较长的行和段落。
|
||||
Overwrite overwrite-mode 次要模式 这一模式用于覆盖缓冲区中任何现有的文本,而不是在当前位置插入文本。在缺省情况下,它与 Ins 键绑定。
|
||||
C c-mode 主要模式 这一模式用于编辑 C 程序源代码。
|
||||
Line Number line-number-mode 次要模式 这一模式用于显示当前行号。
|
||||
Lisp Interaction lisp-interaction 主要模式 这一模式用于编辑和编译 Lisp 代码。
|
||||
Paragraph-Indent Text paragraph-indent-text-mode 主要模式 这一模式是 Text 模式的一种特殊变体,其中的段落移动命令可用于首行缩进的段落,而不仅仅是由空行隔开的段落。
|
||||
TeX tex-mode 主要模式 这一模式用于编辑 TeX 文档。
|
||||
WordStar wordstar-mode 主要模式 这一特殊模式提供了 WordStar 编辑器的键绑定。
|
||||
|
||||
===== 设置模式 =====
|
||||
|
||||
Emacs 模式是一些函数。要调用其中某个函数,您需要输入 M-x,然后给出模式名。
|
||||
现在可以尝试在新的缓冲区中调用 Text 模式:输入 M-x text-mode 并按 Enter。您马上可以看到模式行中的变化,其中用 Text 替换了 Fundamental。
|
||||
在 Text 模式中进行输入
|
||||
Text 模式是一种基本的模式,与 Fundamental 模式相比仅有很少的改变,所以它的优势并不明显;但它是对口语(如英语)文本进行编辑的一个很好的基础。从 TeX 模式到 Outline 模式,许多用于编辑某类文本或文档的特殊模式都是基于 Text 模式的。
|
||||
尝试在新的缓冲区中输入一些文本,继续上一个教程中 William Blake 的主题:
|
||||
__Text 模式下,Tab 键被定义为相对于先前段落的缩进以缩进段落,__如果先前的段落没有缩进,按 Tab 插入一个逐字制表符,移动光标到下一个制表符止。
|
||||
要了解 Text 模式如何处理制表符,可以输入一些带制表符和空格的行:
|
||||
|
||||
===== Abbrev 模式 =====
|
||||
|
||||
Emacs 的缩写 是用一个特定的字符串定义的特殊单词。当在缓冲区中输入一个缩写时(并且 Abbrev 模式已打开),将对这个缩写进行扩展 或者使用定义它的字符串来替换它。Abbrev 模式(一种次要模式)使得您可以对较长的字符串或者短语进行速记,但是您可能还会想到一些其他的使用方式。
|
||||
|
||||
==== 定义一个缩写(需要先启用abbrev-mode) ====
|
||||
|
||||
添加缩写的简单方式是,运行一个 inverse-add 缩写函数 __inverse-add-global-abbrev (C-x a i g)__或者__ inverse-add-local-abbrev(C-x a i l )__。这些函数允许您为缓冲区中的某个单词定义一个缩写,第一个函数可以对当前 Emacs 会话中打开的**任何缓冲区**应用这一缩写,而第二个函数仅对与当前缓冲区具有相同的主要模式的缓冲区定义这一缩写。后者可用于定义仅适用于某些模式的缩写,例如对包含程序源代码的缓冲区中的长变量名进行定义。
|
||||
|
||||
尝试定义一个缩写,并使其应用于所有的缓冲区:
|
||||
在下一新行中,输入一个缩写单词 li,,以使得**光标位于这个单词的末尾**(即在 i 之后)。
|
||||
通过输入 C-x a i g,运行 inverse-add-global-abbrev 函数。
|
||||
在小缓冲区中给出提示的地方定义您的缩写:输入 Little lamb 并按 Enter。
|
||||
|
||||
请注意,您在缓冲区中输入的缩写使用定义它的字符串进行了替换,并且光标移到了这个定义的开头。
|
||||
现在,将光标移动到一个新行,并按您刚刚用过的方法生成一个新的缩写,通过输入 x(缩写不区分大小写),并使用这个字符串 He is 来定义它。
|
||||
现在您已经定义了两个缩写。然而,正如您在模式行里看到的,Abbrev 模式是关闭的。请打开它:输入 __M-x abbrev-mode__。用您刚刚生成的定义删除这两行,然后输入清单 1 中的代码。
|
||||
li 和 x 的缩写按照您的输入进行了扩展,当您完成以上操作后,缓冲区看起来就应该与图 3 所示类似。
|
||||
|
||||
==== Emacs 缓冲区中的缩写扩展 ====
|
||||
|
||||
这个示例显示了如何定义在所有缓冲区中都可以使用的缩写。要定义一个缩写,以使其仅应用于当前模式的缓冲区,可以使用__ C-x a i l__。
|
||||
|
||||
==== 使用一个单词作为缩写的定义 ====
|
||||
|
||||
您还可以**为缓冲区中的单个单词定义缩写**。当您在编写程序源代码并且刚输入了一个较长的变量时,这种方式是特别有用的。
|
||||
要为一个单词定义缩写,可以在光标位于这个单词之后时使用 __C-x a g__。在完成了这个操作之后,当 Abbrev 模式开启时,小缓冲区将提示您用缩写来替代那个单词。同样地,要定义一个仅应用于当前主要模式的缩写,可以使用__ C-x a l__。
|
||||
|
||||
==== 删除缩写 ====
|
||||
|
||||
要删除您在会话中定义的全部缩写,可以使用 kill-all-abbrevs 函数。
|
||||
请尝试下面的操作:键入 __M-x kill-all-abbrevs__。
|
||||
现在,在任何缓冲区(无论其处于何种模式)中都没有使用您所定义的缩写(li、x 和 c)对其进行扩展。再输入两行内容作为结束:
|
||||
|
||||
139
Zim/Utils/emacs/Emacs_编辑环境/程序员的Emacs.txt
Normal file
@@ -0,0 +1,139 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-18T08:56:01+08:00
|
||||
|
||||
====== 程序员的Emacs ======
|
||||
Created Monday 18 April 2011
|
||||
|
||||
===== 加载自己的LISP程序 =====
|
||||
针对程序设计语言的编辑模式可以把emacs从根本上改造为一个语法指导的或语言敏感的(即能够识别和理解某种程序语言语法)的编辑器,从而
|
||||
帮助用户俺自己的风格写出格式整齐,方便阅读的代码。
|
||||
各种编辑模式其实由两大部分组成:用来实现这个编辑模式的LISP程序文件(包),和用来启动这个编辑模式的函数。
|
||||
|
||||
要加载自己定义的函数可以用load函数,但load函数需察看load-path变量的值以确定查找该函数所在程序包的目录:
|
||||
(setq load-path (append load-path (list "~/yourname/lisp"))) 或
|
||||
(setq load-path (cons "~yourname/lisp" load-path))
|
||||
前面一个是将自己的目录添加到load-path的后面,而后一个是插入到load-path的前面。
|
||||
注意:cons后面的参数可以是一个原子项(如字符、字符串、数字),如果想让emacs查找工作目录,该load-path加上一个nil即可如:
|
||||
(setq load-path (cons nil "~yourname/lisp" load-path)
|
||||
由于load-path为一列表型变量,故还可以使用add-to-list函数为其赋值如:
|
||||
(add-to-list 'load-path "~yourname/lisp")
|
||||
|
||||
然后让emacs加载自己的LISP程序包:
|
||||
(load "packagename") ;;注意参数为不带后缀名(.el , .elc )的字符串,emacs启动时自动加载。
|
||||
(autoload ’function "packagename" ) ;; 在执行给定函数时emacs自动加载相应的程序包。
|
||||
还可以用load-file , load-library 等函数。
|
||||
|
||||
有些函数是emacs内置的,它们控制emacs的特性(feature).
|
||||
features变量保存了emacs可以使用的特性,可以用require函数从文件中加载特性。
|
||||
**(require FEATURE &optional FILENAME NOERROR)**
|
||||
|
||||
If feature FEATURE is not loaded, load it from FILENAME.
|
||||
If FEATURE is not a member of the list `features', then the feature is not loaded; so load the file FILENAME.
|
||||
If FILENAME is omitted, the printname of FEATURE is used as the file name,and `load' will try to load this name appended with the suffix `.elc' or
|
||||
`.el', in that order. The name without appended suffix will not be used.
|
||||
If the optional third argument NOERROR is non-nil, then return nil if the file is not found instead of signaling an error.
|
||||
Normally the return value is FEATURE. The normal messages at start and end of loading FILENAME are suppressed.
|
||||
|
||||
**(provide FEATURE &optional SUBFEATURES)**
|
||||
|
||||
Announce that FEATURE is a feature of the current Emacs.
|
||||
The optional argument SUBFEATURES should be a list of symbols listing
|
||||
particular subfeatures supported in this version of FEATURE.
|
||||
|
||||
Emacs能识别的语言元素:
|
||||
单词,如标示符和数字
|
||||
标点符号:包括运算符和语句分割符如分号
|
||||
字符串:字符序列
|
||||
括号:各种括号
|
||||
空白:如空格、制表符
|
||||
注释:注释分隔符中的字符序列
|
||||
|
||||
Emacs可以识别文本编辑时的单词、句子、段落,他允许以这些语言学元素为单位来移动或删除文本,他还知道某些标点符号的用法,如括号的配对高亮。
|
||||
Emacs把语法信息保存在语法表(syntax tables)中,有供全体缓冲区用的全局语法表,每个缓冲区还有一个局部语法表。程序语言的编辑模式还能识别和理解依赖于具体语言的语法如:语句、语句块、函数、子例程、LISP中的S-表达式等。
|
||||
|
||||
==== 基本缩进命令 ====
|
||||
|
||||
TAB 调整当前行的缩进知道与当前环境上下文的格式规则一直,编辑点的位置不变,因此可以在当前行的任意位置使用该键。
|
||||
LINEFEED 命令时TAB+ENTER或C-ENTER,与位于行尾时的C-j一致,都是使新输入的一行自动缩进
|
||||
M-C-q 重新缩进一对匹配的花括号中的所有行,该命令必须位于左花括号所在的行且假设做花括号已经恰当的缩进
|
||||
M-C \ indent-region 对光标和文本块间的每一行按照定义的编程风格进行缩进。
|
||||
M-m back-to-indentation 把光标移动到当前行的第一个非空白字符
|
||||
M-^ delete-indentaion 把当前行合并到上一行去
|
||||
|
||||
Emacs能识别各种语言元素,语句中的分号、冒号、逗号、或括号和井号能字符都是自动缩进的,也就是说在输入这些字符时,emacs会自动的对当前行缩进。
|
||||
|
||||
M-x c-set-style:选择编码风格。内建的cc-mode缩进风格
|
||||
bsd:Style used in code for BSD-derived versions of Unix.
|
||||
cc-mode:The default coding style, from which all others are derived .
|
||||
ellemtel:Style used in C++ documentation from Ellemtel Telecommunication Systems Laboratories in Sweden .
|
||||
gnu:Style used in C code for Emacs itself and other GNU-related programs .
|
||||
java:Style used in Java code (the default for Java mode).
|
||||
k&r:Style of the classic text on C, Kernighan and Ritchie's The C Programming Language .
|
||||
linux:Style used in C code that is part of the Linux kernel.
|
||||
python:Style used in python extensions.
|
||||
stroustrup:C++ coding style of the standard reference work, Bjarne Stroustrup's The C++ Programming Language .
|
||||
user:Customizations you make to .emacs or via Custom (see Chapter 10). All other styles inherit these customizations if you set them.
|
||||
whitesmith:Style used in Whitesmith Ltd.'s documentation for their C and C++ compilers .
|
||||
|
||||
C-c C-a :打开/关闭自动换新行,对应的命令是c-toggle-auto-state,默认为禁用状态。启用后当输入分号、花括号、冒号时emacs自动加上一个换行符并
|
||||
对新行自动缩进
|
||||
C-c C-d:打开/关闭c-toggle-hungry-state。在Del(maybe BackSpace)时,是否自动删除左边所有空格。
|
||||
C-c C-t:同时打开/关闭auto-newline和hungry-delete-key功能
|
||||
M-x check-parens 检查代码中的括号匹配情况
|
||||
|
||||
C++ mode中:
|
||||
C-c ::插入域操作符::
|
||||
|
||||
==== 基本注释命令 ====
|
||||
M-; ident-for-commit 按照comment-colunmn的值进行缩进注释,如果这一行上的文本超过了这一列的值,它将从最后一个字符的位置再右移一个空格
|
||||
然后插入一个注释分隔符并把光标放在分隔符的里面。如果当前行已经存在一个注释但其位置不再commnet-column,则该命令将其重新在这列对齐注释。
|
||||
另外若作用的时一个region,M-;就可以注释或者反注释该区域
|
||||
|
||||
C-M ; 将commnet-colmn设置为编辑点之后的列,左边界为0列
|
||||
M-x uncomment-region 取消文本块的注释
|
||||
|
||||
C-c C-c comment-region 注释文本块
|
||||
C-u C-c C-c uncomment-region 取消文本块的注释
|
||||
M-x kill-comment 清除当前行上的注释
|
||||
|
||||
另外还可以使用emacs的矩形区域填充和剪切功能实现函数块和文本块的快速注释:
|
||||
1.选中一段区域(例如用M-C-h选中一个函数)到最后一行__行首__然后按 __c-x r t__ 输入注释符如//,这时所有行的行首都有这个字符串。
|
||||
2.去除注释可以同样选择区域(由于上一步给行首添加的注释是一个矩形,故这一次只需再选中这个矩形区域即可),最后一行要选择到注释内容后的那个字符,然后__ c-x r k__
|
||||
|
||||
C-j 或M-j 自动缩进式换行注释,注意换行注释时由变量comment-multi-line控制是下一行继续同一条注释还是另外创建一组新的注释分割符
|
||||
M-q 若光标在注释文本中间,则自动进行段落重排,保留缩进和前导字符
|
||||
m-x align 文本的自动对齐
|
||||
|
||||
===== 代码中移动命令 =====
|
||||
M-a 移动到当前语句的开头,注意是语句而不是行首
|
||||
M-e 移动到语句的结尾
|
||||
C-M-f 向前移过某个表达式,命令的执行依赖与光标处的字符(编辑点右边):
|
||||
如果第一个非空白字符为开始分隔符如各种括号,编辑点移到相匹配的结束分隔符之后
|
||||
如果第一个非空白字符为一个记号(如关键字,数字,字符串的引号),编辑点就移到极好的末尾
|
||||
C-M-b 向后移过某个表达式
|
||||
C-M-k 向前剪切某个表达式,剪切后编辑点与C-M-f相同
|
||||
C-M-@ 向前编辑C-M-f移动过的区域
|
||||
C-M-_ 同上
|
||||
|
||||
C-M-a 将光标移动到最近的函数定义的开始
|
||||
C-M-e 将光标移动到下一个函数定义的结尾
|
||||
C-M-h 将光标所在的函数标记为区域
|
||||
|
||||
C-c C-u 移动到当前预处理器条件的开始位置
|
||||
C-c C-n 移动到下一个预处理调剂
|
||||
C-c C-p 移动到上一个预处理条件
|
||||
C-c C-e c-macro-expand 对包含预处理条件的文本块执行实际的预处理过程,可以用于确定有哪些代码是真正会被编译的,其结果放到*Macroexpansion*的窗口中。预处理器由变量c-macro-preprocessor设置。
|
||||
|
||||
===== TAGS的使用 =====
|
||||
:Linux:Utils:emacs:代码搜索
|
||||
|
||||
===== 括号自动补全 =====
|
||||
emacs可以利用skeleton-pair-insert-maybe来实现,添加一下代码到.emacs中。这对编写lisp很方便但是在写c/c++ java的时候就没有多大的用处了。当然有更好用的yasnippet,但是需要按一个扩展snippet的键。
|
||||
|
||||
( setq skeleton-pair-alist nil)
|
||||
(global-set-key (kbd "[") 'skeleton-pair-insert-maybe)
|
||||
(global-set-key (kbd "(") 'skeleton-pair-insert-maybe)
|
||||
(global-set-key (kbd "{") 'skeleton-pair-insert-maybe)
|
||||
(global-set-key (kbd "<") 'skeleton-pair-insert-maybe)
|
||||
(global-set-key (kbd "\"") 'skeleton-pair-insert-maybe)
|
||||
185
Zim/Utils/emacs/Emacs定制.txt
Normal file
@@ -0,0 +1,185 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-18T21:32:57+08:00
|
||||
|
||||
====== Emacs定制 ======
|
||||
Created Monday 18 April 2011
|
||||
|
||||
屏幕上显示的任何东西,任何命令,任何按键动作和任何一条消息等几乎都可以定制。
|
||||
LISP函数的调用形式是 (function-name argumets-lists)
|
||||
|
||||
当.emacs配置文件出现问题时可以在命令行上指定-q参数,Emacs将不运行这个文件中的配置指令。
|
||||
-u username 用于测试另外用户的配置文件
|
||||
|
||||
==== 1.键盘的定制 ====
|
||||
按键的动作是通过按键序列与命令关联起来的。Emacs里每个按键动作都会运行一个命令对于可打印字符运行self-insert-command。
|
||||
键位映射表(keymap)是由多个按键绑定构成的一个集合。Emacs最基本的默认按键绑定保存在名为global-map的全局键位映射表中。
|
||||
局部键位映射表local-map 是每个模式对应的一个映射表,作用是实现对应模式的特殊命令,不同的编辑模式对应的局部表不同。每个缓冲区的模式
|
||||
都有一个本地键盘映射表,该表首先用于对应窗口的按键操作,若没有按键定义项,就会察看global-map表。
|
||||
对于绑定到组合键(多余一个字符的按键序列)的命令,比如M-d 是怎样被查到的呢?
|
||||
按键时Emacs执行的循环操作是:基本的转换操作是使用输入字符的ASCII值来索引具有128个元素的一个向量即keymap,有时一个字符的第8位配解释为META字符,所有的META字符将包含ESCAPE前缀,无论是否以该方式输入。
|
||||
对于组合键如C-x 、M-、C-c等其实是被绑定到一些特殊的内部函数上,而这写函数会让Emacs等到另一个按键配按下胡在去另外一个键位映射图中查找
|
||||
该按键的绑定定义。如果后面的按键在一秒后没有按下就会在minibuffer中现实C-x-等。供C-x ,M- , M-x ,C-c使用的键位映射图分别为 ctl-x-map和esc-map
|
||||
mode-specific-map. C-c 组合键是为关联与某具体编辑模式的局部键位映射图准备的。
|
||||
通过在键位映射图中添加或写改(如果已经存在)定义项可以创造出自己的按键绑定,可以使用三个函数:
|
||||
(define-key keymap "keystroke" 'command-name)
|
||||
(global-set-key "keystroke" 'command-name)
|
||||
(local-set-key "keystroke" 'command-name)
|
||||
第一个是通用的,可以用来绑定任何一个键位映射图中的按键,但需要知道图名称。
|
||||
把按键绑定插入到.emacs文件后,需要运行(或者称为求值)这个文件才能生效,可以用M-x eval-buffer 或 C-x C-e 执行光标所在的那一行上的LISP代码。
|
||||
|
||||
特殊字符的表达式
|
||||
\C-x C-x x为任意字符
|
||||
\C-[ 或\e ESC; 转义符
|
||||
\C-j 或 \n LINEFEED; 换行符
|
||||
\C-m 或 \r RETURN ;回车符
|
||||
\C-i 或\t TAB;制表符
|
||||
由于转移字符只能用于有限的几个字符(如\o ,\p,\q等就没有意义),因此一般应用kbd函数来生成任意含有特殊含义的字符串。
|
||||
kbd函数的调用形式为:
|
||||
(kbd string)
|
||||
返回string对应的emacs控制序列,使用kbd函数的好处是string中各特殊控制字符可以用三个大些字母来表示,功能键可以用尖括号括起来的键名表示,
|
||||
按键前缀可以用但个大写字母加段横线表示,这避免了keystroke中过多了转义字符。
|
||||
string的格式为:
|
||||
(edmacro-mode) 下段说明来自这个函数的帮助文件
|
||||
Text is divided into "words" separated by whitespace. Except for the words described below, the characters of each word go directly
|
||||
as characters of the macro. The whitespace that separates words is ignored. __ Whitespace in the macro must be written explicitly__,
|
||||
as in "foo SPC bar RET".
|
||||
* The special words __RET, SPC, TAB, DEL, LFD, ESC__, and __NUL__ represent special control characters. The words must be written in uppercase.
|
||||
它们都是三个大写字母
|
||||
* A word in angle brackets, e.g., __<return>, <down>, or <f1>__, represents a function key. (Note that in the standard configuration, the
|
||||
function key <return> and the control key RET are synonymous.) You can use angle brackets on the words RET, SPC, etc., but they
|
||||
are not required there.
|
||||
* Keys can be written by their ASCII code, using __a backslash followed by up to six octal digits__. This is the only way to represent keys
|
||||
with codes above \377.
|
||||
* One or more prefixes __M- (meta), C- (control), S- (shift), A- (alt), H- (hyper), and s- (super)__ may precede a character or key notation.
|
||||
For function keys, the prefixes may go inside or outside of the brackets: C-<down> = <C-down>. The prefixes may be written in
|
||||
any order: M-C-x = C-M-x.注意shift必须和C或M或A一起使用"S-SPC"是错误的,可以用"C-S-SPC"
|
||||
. __ Prefixes are not allowed on multi-key words, e.g., C-abc__, except that the Meta prefix is allowed on a sequence of digits and optional
|
||||
minus sign: M--123 = M-- M-1 M-2 M-3.
|
||||
* The `^' notation for control characters also works: __ ^M = C-m__.
|
||||
* Double angle brackets enclose command names: <<next-line>> is shorthand for M-x next-line RET.
|
||||
* Finally, REM or ;; causes the rest of the line to be ignored as a comment.
|
||||
|
||||
Any word may be prefixed by a multiplier in the form of a decimal number and `*': 3*<right> = <right> <right> <right>, and
|
||||
10*foo = foofoofoofoofoofoofoofoofoofoo.
|
||||
Multiple text keys can normally be strung together to form a word, but you may need to add whitespace if the word would look like one
|
||||
of the above notations: `; ; ;' is a keyboard macro with three semicolons, but `;;;' is a comment. Likewise, `\ 1 2 3' is four keys but `\123' is a single key written in octal, and `< right >' is seven keys but `<right>' is a single function key. When in doubt, use whitespace.
|
||||
|
||||
常见的错误:
|
||||
(global-set-key (kbd "S-m") 'goto-line) ;;; S- 不能单独跟一个字符
|
||||
(global-set-key (kbd "C-xa") 'goto-line) ;; C-后面只能连续跟一个字符 ,应为"C-x a"
|
||||
(global-set-key (kbd "abC-m") 'goto-line) ;;; a不是一个命令前缀
|
||||
(global-set-key (kbd "C-aC-bC-m") 'goto-line) ;; 不同的控制字符相互间必须有空格分开
|
||||
(global-set-key (kbd "C-a C-b") 'goto-line) ;; C-a 并没有一个已经定义的键映射前缀函数绑定(缺省绑定的有 C-x -, C-x-4- ,M- , C-h-,C-c-),
|
||||
(global-set-key (kbd "C-x C-a C-b") 'got-line) ;; 虽然C-x是已经定义的映射前缀但C-a并不是下一级的映射前缀
|
||||
|
||||
一般一个可打印字符的绑定可以直接用“a”的形式,不可打印如带有CTL或ALT前缀的单一字符可用"C-a" 或“^A"或"M-a".
|
||||
对于单个字符,用local-set-key是定义在major-mode的局部缓冲区列表中,用global-set-key是定义到全局缓冲区列表中。
|
||||
|
||||
对于由两个字符序列的绑定除非用已经定义的前缀(因为它们都有相应的keymap,这时其实还是一级表,C-x等其实是一个前缀命令)如C-x (ctl-x-map) , C-x 4 (ctl-x-4-map), C-h (help-map) , C-c(mode-specific-map) ,否则必须先定义一个keymap。
|
||||
"C-x a" "C-x 4a" "C-x 4 a" "C-h 4" " C-h a" "C-c a" 都是合法的(它们都是把a绑定的命令添加到对应的keymap中),但"C-x ad"等是不合法的,除非先在C-x的映射表中定义一个对应与a的映射表(这时形成了一个两级表)如:
|
||||
(setq tmpkeymap (make-keymap)) ;; set up the keymap var
|
||||
(define-key ctl-x-map "a" tmpkeymap) ;; add the tmpkeymap to exit ctl-key-map
|
||||
然后就可以使用"C-x ad"等以"C-x a 任意字符” 的形式绑定命令了如:
|
||||
(define-key tmpkeymap "d" 'forward-word) ;; add a key to tmpkeymap ,由于制定了表,故无需再加前缀
|
||||
或(global-set-key (kbd "C-x ad") 'forward-word) ;;没有指定表,故需加前缀
|
||||
|
||||
也可以定义自己的前缀表,方法和上面的类似:
|
||||
(setq map (make-keymap))
|
||||
(define-key global-map (kbd "C-a") map)
|
||||
然后就可以往map表中绑定命令了:
|
||||
(define-key map "d" 'forward-line) ;指定表时不需加前缀
|
||||
(global-set-key (kbd “C-a d") 'forward-line) ;;不指定表时需指定前缀
|
||||
|
||||
注意如果上面的按键不用kbd函数的话,要使用转移字符转义如:
|
||||
"\C-a d" "\M-a d"
|
||||
对于\C-和\M-也可以直接用"\ead" 或"\"
|
||||
|
||||
===== 2.Emacs变量 =====
|
||||
按键改变的是操作emacs的界面,而变量(或选项)控制着emacs的各种行为。可以说只要相对emacs的某个方面进行定制,就肯定会有一个
|
||||
与之对应的控制变量(特别是想改变的东西涉及到一个数字或涉及到真、假条件时更是如此)。
|
||||
当不知道变量名时可以通过apropos命令查出是否有与想定制相关的变量。
|
||||
(setq varname val) ;;设置局部变量值
|
||||
(setq-default varnaem val) ;;设置默认值(全局变量值)
|
||||
但没有方法判断某一个变量是只有一个全局取值还是既有默认值又有局部值,最佳的策略是先尽量使用setq命令,无效时再使用setq-default.
|
||||
|
||||
变量值的类型:
|
||||
字符串值:必须放在双引号中,特殊字符要转义
|
||||
字符值:必须用问号做前缀,而且不能放在双引号中
|
||||
符号值:以单引号开头,后跟符号名(通常位函数名或变量名),表示不执行函数和获得变量的值
|
||||
|
||||
===== 自动模式的定制 =====
|
||||
|
||||
M-x c-mode:进入C mode模式
|
||||
M-x c++-mode:进入C++ 模式
|
||||
|
||||
===== 1.文件名与模式自动匹配 =====
|
||||
emacs能根据文件后缀名自动进入相应的模式,后缀名与主编辑模式的关联关系是有列表型变量auto-mode-alist管理的。
|
||||
这个变量是一个(regexp . mode) 形式的数据组列表,regexp为正则表达式,mode为启动某一个主编辑模式的函数名。
|
||||
注意:regexp可以匹配文件名的任意部分。
|
||||
例如:
|
||||
(setq auto-mode-alist (cons '("\\.org$" . org-mode) auto-mode-alist))
|
||||
注意: cons 后面必须要有一个单引号,org-mode前必须要有一个句号,记号 '(x . y)是用来把x和y配对组成一个数据组的LISP语法。注意正则表达式中用两个\\表示一个\,这是因为emacs在读正则表达式时将其中的两个\\转为一个\传给相应的函数。
|
||||
|
||||
==== 2.缺省模式 ====
|
||||
如果打开的文件没有匹配上auto-mode-alist中的任何一个表达式,emacs就会把放到default-major-mode变量中的只作为基本默认模式。
|
||||
(setq default-major-mode 'text-mode)
|
||||
|
||||
|
||||
====== 对现有模式进行定制 ======
|
||||
|
||||
Emacs的各种主编辑模式都有一些可以把你编写的代码添加到它上面去的挂钩,他们的名字一般叫做mode-hooks.
|
||||
Emacs内建的各主编辑模式都有一个名为"mode-name-hook"的编辑模式挂钩,其中的mode-name是该编辑模式的名称或启动他的函数的名字。
|
||||
如C模式的c-mode-hook,shell有一个shell-mode-hook.
|
||||
|
||||
挂钩是一种特殊的变量,它的值代表一些LISP代码,这些代码会在相应的编辑模式启动时得到运行。
|
||||
启动一个编辑模式就等于运行一个LISP函数,该函数通常要设置按键绑定、创建局部变量、创建缓冲区,如果编辑模式有挂钩,那么该函数的所做的
|
||||
最后一件事就是运行挂钩变量中的LISP代码。
|
||||
|
||||
LISP基本函数lambda可以用来定义函数,它与defun的区别是lambda定义的函数没有名字即为匿名函数,其语法如下:
|
||||
(lambda (args)
|
||||
code-block)
|
||||
如果想把一个用lambda定义的函数作为一个值赋给某个变量,就必须对他进行转义以防止它被求值(即防止它被调用运行)如:
|
||||
(setq var-name
|
||||
'(lambda ()
|
||||
code)
|
||||
在编写编辑模式挂钩的代码时可以用:
|
||||
(setq mode-name-hook
|
||||
'(lambda ()
|
||||
code for mode hook))
|
||||
|
||||
如果使用setq来定义你自己的挂钩,就会覆盖掉原有的挂钩,要想避免出现这样的情况,就可以使用add-hook函数
|
||||
(add-hook 'mode-name-hook
|
||||
'(lambda ()
|
||||
code for mode hook))
|
||||
|
||||
编辑模式挂钩最常用的用途时为某个编辑模式的特殊命令修改一个或多个按键绑定。可以自己定义一些函数然后将其绑定到某一模式的键盘映射表上,也可以为某一模式现有的函数设置按键绑定。
|
||||
按照规定定义某一编辑模式的正确方法是必须通过他的挂钩来进行,但如果只是给变量重新设置一个值,就可以不用使用挂钩;但如果想运行某些编辑模式相关的函数就必须使用挂钩。这是因为:
|
||||
某一个编辑模式的局部变量是属于局部范畴的,如果没有启动该模式,他们就不会存在。但只要在.eamcs文件中包含一条给这个变量赋值的setq语句,那么不管是否使用该模式,这个变量就已经存在了。Emcas能够很好地应付这种情况,当加载这种模式时,它会注意到这个已经设置的变量值,于是就不会覆盖掉它。
|
||||
但函数的情况就不同了 ,如果.emacs文件里有一个属于某个编辑模式的局部函数,当这个模式没有启动时,Emacs会给出一条出错信息。因为它根本不知道该函数属于那个编辑模式,因此必须把这个函数的调用语句放在他所在模式的钩子函数里。
|
||||
|
||||
|
||||
===== 交换Control和alt的位置 =====
|
||||
|
||||
!
|
||||
! Swap Caps_Lock and Control_L
|
||||
!
|
||||
!remove Lock = Caps_Lock
|
||||
!remove Control = Control_L
|
||||
!keysym Control_L = Caps_Lock
|
||||
!keysym Caps_Lock = Control_L
|
||||
!add Lock = Caps_Lock
|
||||
!add Control = Control_L
|
||||
|
||||
|
||||
!swithc alt and ctl
|
||||
remove mod1 = Alt_L
|
||||
remove Control = Control_L
|
||||
keycode 37 = Alt_L
|
||||
keycode 64 = Control_L
|
||||
add Control = Control_L
|
||||
add mod1 = Alt_L
|
||||
|
||||
|
||||
|
||||
|
||||
157
Zim/Utils/emacs/IRC.txt
Normal file
@@ -0,0 +1,157 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-03T14:54:24+08:00
|
||||
|
||||
====== IRC ======
|
||||
Created Sunday 03 April 2011
|
||||
|
||||
ERC, emacs irc client, 即是 emacs 里登录 irc 的客户端。irc 是什么? internet relay chat, 简单地说,就是用于群聊的。一帮无聊的 geeks 成天没事干,就在上面灌水,所以上面的 channel 技术类的占绝大数,比如 emacs, c++, debian, scheme 等等。
|
||||
|
||||
好,开始 ERC 之旅,先让我们登录到 #emacs-cn 上去:
|
||||
|
||||
a) M-x erc-select
|
||||
|
||||
host: irc.debian.org
|
||||
port: 6667 到 7000 随便用一个
|
||||
username: 先随便填一个,比如 foo
|
||||
password: 还没注册的可以直接回车
|
||||
|
||||
b) 这时候你就进入了一个名字类似 “irc.debian.org:6669″ 的 server buffer. 接着执行:
|
||||
|
||||
ERC> /join #emacs-cn
|
||||
|
||||
就进入 #emacs-cn channel 啦!
|
||||
|
||||
c) 如何注册
|
||||
|
||||
切换到刚才那个 server buffer, 输入:
|
||||
|
||||
ERC> /msg nickserv help register
|
||||
|
||||
按着提示一步一步来就行,根据 irc server 的不同,有些会需要你用有效邮箱来确认一下。注册 id 的好处就是,这个 id 就不会被别人抢走了,比如有人已经用 foo 登录了,但这被你注册了,你连进去的时候,就能把名字抢过来,而对方可能会变成 foo` 之类的别名。
|
||||
|
||||
以上其实对于所有 irc client 来讲都是通用的。接下来是我的 ERC 一些配置供参考:
|
||||
|
||||
1. 基本设置
|
||||
|
||||
编码,尽量 utf-8 (#emacs-cn 也是用 utf-8):
|
||||
|
||||
(setq erc-default-coding-system '(utf-8 . utf-8))
|
||||
|
||||
如果某个 channel 是别的编码,也可以单独设置,例如国内某个 irc server 上 #linuxfire 就是用 gbk 编码,我们单独为它设置:
|
||||
|
||||
(setq erc-encoding-coding-alist '(("#linuxfire" . chinese-iso-8bit))
|
||||
|
||||
设置 nick, 全名: nick 就是登录时用的,full name 是别人查询你的时候显示的信息。(类似BBS 的 C-a )
|
||||
|
||||
|
||||
(setq erc-nick "xwl"
|
||||
erc-user-full-name "William Xu")
|
||||
|
||||
2. 登录后自动加入预定的 channels
|
||||
|
||||
(erc-autojoin-mode 1)
|
||||
(setq erc-autojoin-channels-alist
|
||||
'(("oftc.net" ; debian.org 是它的别名
|
||||
"#debian-zh"
|
||||
"#emacs-cn")))
|
||||
|
||||
3. 连接服务器或进入聊天室后自动执行预设操作
|
||||
ERC 提供各种各样的 hook 让你在某个操作(登入 server, 进入channel等)之后执行一些你预设的操作。比如如果你有某个 channel 的管理员权限,可以在加入聊天室时自动转换到管理员身份:
|
||||
|
||||
(defun xwl-erc-auto-op ()
|
||||
(let ((b (buffer-name)))
|
||||
(when (string= b "#emacs-cn")
|
||||
(erc-message "PRIVMSG" (concat "chanserv op " b)))))
|
||||
|
||||
(add-hook 'erc-join-hook 'xwl-erc-auto-op)
|
||||
|
||||
4. 过滤信息
|
||||
如果你对某些消息或者某个人说的话特别感兴趣,我们可以通过关键字匹配对相关信息进行高亮。例如:
|
||||
|
||||
(erc-match-mode 1)
|
||||
(setq erc-keywords '("emms" "python"))
|
||||
(setq erc-pals '("rms"))
|
||||
|
||||
相反地,如果你对某些消息不感兴趣,比如有人进来啦,有人出去啦,如此这般一下就不会看到了:
|
||||
|
||||
(setq erc-ignore-list nil)
|
||||
(setq erc-hide-list
|
||||
'("JOIN" "PART" "QUIT" "MODE"))
|
||||
|
||||
5. 新信息提醒
|
||||
|
||||
信息一般可分为三种:
|
||||
|
||||
1) 某人悄悄跟你说话(即所谓的 private message),这会打开一个新小窗,即 buffer.
|
||||
|
||||
ERC>/msg NICK how are you doing
|
||||
|
||||
2) 某人公开地跟你说话,即别的在 channel 里的人也能看到。一般来说,习惯用 nick加 `:’ 表示。(要输入某人 nick 的时候,首字母加 TAB 就能帮你补全,一次不行,多 TAB 几次可以选择)
|
||||
|
||||
<xwl> ahei: 你可以 match regexp,
|
||||
|
||||
3) 别的情形。
|
||||
|
||||
ERC 会通过 erc-modified-channels-object 来设置 mode line,提示有新消息,类似:
|
||||
|
||||
[#o: 38, #emacs-cn: 5]
|
||||
|
||||
为什么要区分以上三种情形呢? 因为我们可以对不同信息,用不同的颜色在mode line 来提示,这样方便你决定是不是要及时地去查阅这条消息。
|
||||
|
||||
ERC 本身只在 mode line 提示新消息,如果你切换到别的程序去了,比如在firefox 里看 ppmm,还想被提醒的话,可以借助一些外部工具来实现。mac 下用 growl,linux 可以用 zenity,windows 不知有什么类似工具? 给个例子:
|
||||
|
||||
(defun xwl-erc-text-matched-hook (match-type nickuserhost message)
|
||||
"Shows a growl notification, when user's nick was mentioned.
|
||||
If the buffer is currently not visible, makes it sticky."
|
||||
(when (and (erc-match-current-nick-p nickuserhost message)
|
||||
(not (string-match (regexp-opt '("Users"
|
||||
"User"
|
||||
"topic set by"
|
||||
"Welcome to "
|
||||
"nickname"
|
||||
"identified"
|
||||
"invalid"
|
||||
))
|
||||
message)))
|
||||
(let ((s (concat "ERC: " (buffer-name (current-buffer)))))
|
||||
(case system-type
|
||||
((darwin)
|
||||
(xwl-growl s message))))))
|
||||
|
||||
(add-hook 'erc-text-matched-hook 'xwl-erc-text-matched-hook)
|
||||
|
||||
(defun xwl-growl (title message)
|
||||
(start-process "growl" " growl" growlnotify-command title "-a" "Emacs")
|
||||
(process-send-string " growl" message)
|
||||
(process-send-string " growl" "\n")
|
||||
(process-send-eof " growl"))
|
||||
|
||||
6. 时间戳
|
||||
|
||||
(erc-timestamp-mode 1)
|
||||
|
||||
下面这个变量可以控制时间戳的显示方式,比如位置什么的,默认值:
|
||||
|
||||
(setq erc-insert-timestamp-function 'erc-insert-timestamp-left)
|
||||
|
||||
7. log
|
||||
我们可以将 channel 里的聊天记录都保存下来,方便日后查询,或者有时候你的 emacs 突然挂掉的时候,还能找到挂之间有没有人对你说了什么。
|
||||
|
||||
|
||||
(require 'erc-log)
|
||||
(erc-log-mode 1)
|
||||
(setq erc-log-channels-directory "~/var/erc/"
|
||||
erc-save-buffer-on-part t
|
||||
erc-log-file-coding-system 'utf-8
|
||||
erc-log-write-after-send t
|
||||
erc-log-write-after-insert t)
|
||||
|
||||
(unless (file-exists-p erc-log-channels-directory)
|
||||
(mkdir erc-log-channels-directory t))
|
||||
|
||||
最后,ERC 上 irc 还是蛮舒服的,因为所有的、你熟悉的 emacs 编辑命令都在那里! 国内 irc 用户还是少了点,对岸台湾倒是蛮多的。大家有空就上来玩吧~ 要是想看我的配置可以在 github.com 上看我的配置文件:
|
||||
|
||||
http://github.com/xwl/xwl-emacs-config/blob/master/.emacs.d/site-lisp/config/xwl-erc.el
|
||||
|
||||
|
||||
90
Zim/Utils/emacs/LISP模式.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-18T09:45:22+08:00
|
||||
|
||||
====== LISP模式 ======
|
||||
Created Monday 18 April 2011
|
||||
|
||||
===== Emacs提供了三种LISP编辑模式 =====
|
||||
emacs-lisp-mode 用来编辑Emacs LISP代码
|
||||
lisp-mode 用来编辑其他系统的LISP代码
|
||||
lisp-interaction-mode 用来编辑和运行Emacs LISP代码(交互式)
|
||||
这三种编辑模式的基本功能是一样的,区别是他们各自对LISP代码运行的支持功能上。
|
||||
|
||||
**S-表达式**(syntactic expression , 语法表达式)指的是任意一个没有语法错误的LISP表达式,他可以是一个原子项(数字、字符串、字符、符号、变量等)或者是一个放在括号中的列表。**列表**(list)是S-表达式的特殊形式,而函数定义又是列表的特殊形式。
|
||||
|
||||
===== S-表达式处理命令 =====
|
||||
对S-表达式进行处理的命令到底采用什么动作,取决于调用命令时插入点的位置,如果光标在一个左括号(或它前面的一个空白位置),将被处理的是以这个左括号开始列表。
|
||||
如果光标在字母或数字等其它字符(或他们前面的一个空白位置)将被处理的S-表达式将是一个原子项(符号、变量或常数)
|
||||
M-a 移动到当前语句的开头,注意是语句而不是行首
|
||||
M-e 移动到语句的结尾
|
||||
C-M-f 向前移过某个表达式,命令的执行依赖与光标处的字符(编辑点右边):
|
||||
如果第一个非空白字符为开始分隔符如各种括号,编辑点移到相匹配的结束分隔符之后
|
||||
如果第一个非空白字符为一个记号(如关键字,数字,字符串的引号),编辑点就移到极好的末尾
|
||||
C-M-b 向后移过某个表达式
|
||||
C-M-k 向前剪切某个表达式,剪切后编辑点与C-M-f相同
|
||||
C-M-@ 向前编辑C-M-f移动过的区域
|
||||
C-M-_ 同上
|
||||
|
||||
C-M-a 将光标移动到最近的函数定义的开始
|
||||
C-M-e 将光标移动到下一个函数定义的结尾
|
||||
C-M-h 将光标所在的函数标记为区域
|
||||
上面3个命令,只有在当前函数的defun出现的代码行才能正常工作。
|
||||
|
||||
M-C-n forward-list 移动到上一个列表
|
||||
M-C-p backware-list 移动到下一个列表
|
||||
M-C-d down-list 向前移动,进入到下一级括号层次
|
||||
M-C-u backward-up-list 向后移动,退出当前括号层次
|
||||
上面4个命令,光标的前后必须要有一个左括号或右括号,如果没有,Emacs就会报错。
|
||||
|
||||
|
||||
===== 缩进样式 =====
|
||||
|
||||
Emacs LISP函数调用使用的基本的缩进量是2,只要下一行的代码又向下嵌套了一级(如引入了一个语句块),Emacs就将使用这个值对其缩进。如:
|
||||
(defun time (x y)
|
||||
(let (i 0)
|
||||
(result 0)
|
||||
(while (< i x)
|
||||
(setq result (+ result y)
|
||||
i (1+ i)))
|
||||
result))
|
||||
|
||||
如果函数有一个以上的参数,则该函数的函数名及第一个参数将出现在第一个代码行上,其他参数分别列在后续的代码行上,
|
||||
并且要雨第一个参数对齐,如:
|
||||
(function-name arg1
|
||||
arg2
|
||||
arg3
|
||||
... )
|
||||
|
||||
类似关键字的let和while等术语实际上是函数调用,但LISP编辑模式能根据自己对这类函数的理解对他们进行特殊的缩进安排。
|
||||
另外LISP编辑模式习惯于把多个右括号都连续地写在同一行的最末尾,而不是把他们分别写到不同的代码行上。
|
||||
|
||||
LISP编辑模式(非最后一个交互式模式)为TAB和LINEFEED(C-j)提供了换行和自动缩进的功能,同时还提供了M-C-q对光标后面的S-表达式的每一行进行缩进(例如把光标放在函数的定义行,就可以对整个函数中的语句进行缩进)
|
||||
|
||||
LISP编辑模式的注释由通用注释命令M-;负责,如果注释内容占据了一整行,这时按下TAB键则将注释移到comment-column指定的位置,为了避免出现这种情况,可以用两个
|
||||
或多个分号来代替单个分号。在注释时可以使用M-j在下一行继续写注释。
|
||||
|
||||
===== 各模式都有的功能 =====
|
||||
|
||||
==== Emacs LISP: ====
|
||||
Emacs LISP 是为运行Emacs内部的LISP代码准备的,所以支持直接运行输入的代码。
|
||||
可以用M-C-x eval-defun 把光标附近的函数定义进行求值,同时把对该函数保存起来,以便在同一会话中调用该函数。
|
||||
可以用M-TAB lisp-complete-symbol 自动补充光标前面的符号(如变量、函数名)。
|
||||
|
||||
可以用M-: eval-expression 在辅助输入缓冲区中输入任何一种形式的单行LISP表达式,然后对该表达式求值,并把结果显示在辅助输入缓冲区中。
|
||||
这非常适合检查变量的值,试用哪些键没有绑定,或需要额外参数的内置函数。
|
||||
|
||||
同时可以用C-x C-e eval-last-sexp 运行光标所在行的LISP语句,比把结果显示在辅助缓冲区中。
|
||||
|
||||
==== LISP模式: ====
|
||||
是为非Emacs内置的LISP语言处理工具而编写的代码服务的,他提供了用来与外部LISP解释器进行通信的接口。
|
||||
C-c C-z run-liisp 启动一个用户系统的LISP解释器进程,并且创建一个*lisp*编辑缓冲区,供输入和输出。如果把光标放在某个函数的定义当中再按下M-C-x就能把函数的定义放到LISP子进程中。
|
||||
|
||||
==== 交互式模式 ====
|
||||
*scratch*编辑缓冲区默认进入的模式。
|
||||
除了把LINEFEED即C-j绑定为eval-print-last-sexp外,交互式模式与Emacs LISP模式可以说是一模一样,如果想获得其它模式绑定在LIENFEED上的换行及缩进的效果,必须先按回车再按TAB。
|
||||
在交互式模式中可以利用LINEFEED检查变量的值、输入函数定义和运行函数(Emacs会把函数的定义保存下来供以后使用)等。注意:交互模式的LINEFEED要求光标必须位于
|
||||
定义函数的结尾行。
|
||||
|
||||
|
||||
|
||||
279
Zim/Utils/emacs/LISP语言.txt
Normal file
@@ -0,0 +1,279 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-18T14:53:04+08:00
|
||||
|
||||
====== LISP语言 ======
|
||||
Created Monday 18 April 2011
|
||||
|
||||
对于Emacs,无论发现缺少何种功能,都可以动手用LISP程序实现它。实际上可以把Emacs看作是一个带有很多内部函数的LISP系统,其中很多函数是用来实现文本处理、
|
||||
窗口管理、文件I/O和其它与文本编辑有关的函数。Emacs源代码使用C写的,它实现了LISP解释器、LISP指令和一些最基本的文本编辑命令。Emacs的其它功能时在它们基础上用
|
||||
一个规模巨大的内部LISP代码层实现的。
|
||||
|
||||
===== 基本元素 =====
|
||||
函数、变量、原子项是LISP语言的最基本元素,函数是LISP语言唯一的程序单元。
|
||||
LISP中的函数定义为由上述基本元素组成的各种列表(list),而且这种列表往往还嵌套调用其它现有的函数。一切函数都可以有返回值,调用的一个函数的返回值就是定义该函数时的最后一个列表项的值。嵌套在另外一个函数里的某个函数调用相当于其它程序设计语言中的一条语句(statement)。函数调用的语句
|
||||
(function-name argument1 argument2 ...)
|
||||
这条语句适合一切函数的调用,那些相当于其它程序语言中的算术或比较操作符的函数也不例外。
|
||||
LISP中的变量没有类型的概念,一个变量可以去任意的类型。原子项时任意类型的值,可以是整数、浮点数、字符、字符串、布尔值、符号,同时也可以是编辑缓冲区、窗口、进程等特殊的Emacs类型。
|
||||
整数
|
||||
浮点数
|
||||
字符:LISP字符必须要由一个前导的问号,不加引号,ESC,LINEFEED、TAB分别用\e,\n,\t表示,其它控制字符要加上前缀"\C-"如?\C-a
|
||||
字符串:必须放在一对双引号中间,字符串中的引号和反斜线字符必须用转义字符引导。
|
||||
布尔值:t表示真,nil表示假,任何一个不是nil的值意味着真,在需要nil的场合,null或空值表示假
|
||||
符号:LISP语言中各种事物的名字,如变量名函数名。有时我们需要的事物的名字而不是他们的值,这就需在事物的名字前加一个单引号。
|
||||
|
||||
(setq auto-save-interval 80)
|
||||
(setq thisvar thisvalue
|
||||
thatvar thatvalue
|
||||
theotherval theothervalue)
|
||||
setq的返回值就是最后一个赋值。
|
||||
|
||||
列表时LISP语言中的一个基本概念,它充分体现了堆栈结构的本质特性。列表时把LISP与其它程序设计语言区分开来的主要概念。这种数据结构有两部分组成:头元素和剩下的尾元素。出于历史原因,LISP称之为car和cdr,前者为列表里第一个东西,后者为列表中剩余的东西。如果给car和cdr提供一个列表参数,他们就返回列表的头和尾元素。cons函数带两个参数,而这两个参数分别设为列表的头元素和尾元素。list函数以多了元素为输入参数,用他们构造出一个列表。
|
||||
(list 1 2 3 4)
|
||||
(cons 1 (list 2 3 4))
|
||||
上面两条语句功能相同。
|
||||
堆栈可以很容易地用列表实现:
|
||||
(setq calc-stack (cons x calc-stack))
|
||||
获得栈顶的元素:
|
||||
(car calc-stack)
|
||||
弹出栈顶的元素:
|
||||
(setq calc-stack (cdr calc-stack))
|
||||
|
||||
列表的元素可以使其它包括列表在内的任何东西,这就是人们把列表称为递归数据结构的原因。事实上,对LISP语言里任何一种东西来说,如果他不是一个原子项,就会是一个列表。这里面也包括函数,它可以看作由一个函数名、参数、准备求值的表达式等元素组成的列表。
|
||||
|
||||
===== 函数的定义 =====
|
||||
在LISP语法中,短划线字符时在变量名、函数名等语言元素中用作间隔符的字符,LISP是一种很古老的语言。因此语法对程序员并不是很友好,用LISP语言写出的程序会使用大量的列表,也就是使用大量的括号。人们习惯于将多个括号集中放在代码的末尾而不是把它们分别放在一行并于对应的左括号对齐。这导致其可读性变差。简单的函数实例如下:
|
||||
(defun count-words-buffer () 1
|
||||
(interactive) 2
|
||||
(let ((count 0)) 3
|
||||
(goto-char (point-min)) 4
|
||||
(while (< (point) (point-max)) 5
|
||||
(forward-word 1) 6
|
||||
(setq count (1+ count))) 7
|
||||
(message "buffer contains %d words." count))) 8
|
||||
(count-words-buffer) 9
|
||||
|
||||
defun定义了一个函数和他的参数,defun本身也是一个函数,他会在被调用时定义一个新的函数,返回值是一个符号即定义的函数名,函数的参数都放在括号里,形成一个由变量名组成的列表,如果在某个参数前加一个&optional,就可以把这个参数设为可选参数,如果一个参数是可选的并且在调用时没有给出,他的取值就是nil。
|
||||
|
||||
let函数的基本调用格式是:
|
||||
(let ((var1 value1)
|
||||
(var2 value2)
|
||||
...)
|
||||
statement-block)
|
||||
|
||||
let先对变量var1 var2进行定义,并把他们的初始值设为value1 value2等,接着let执行他的语句块部分,语句块时顺序排列的一组函数调用。
|
||||
let做了三件事:
|
||||
定义(或声明)了一个由变量组成的列表
|
||||
给变量设置初始值
|
||||
创建一个可以使用声明的变量的语句块,let的语句块也叫做变量的作用域。
|
||||
|
||||
LISP语言中while结构的基本格式是:
|
||||
(while condition
|
||||
statement-block)
|
||||
循环条件condition是一个值(一个原子项、一个变量或者是一个有返回值的某个函数),while对其测试判断是否为nil。对于无限循环可以用C-g来结束LISP语句的执行。<函数及其它条件比较函数返回的都是一个布尔值。
|
||||
|
||||
(1+ count),函数1+是(+ 1 variable-name)的缩写形式,主要函数的返回值是最后一个列表项。
|
||||
|
||||
内部函数message在辅助输入区中显示一条信息,其第一个参数是一个输出格式字符串,其它的为参数名。
|
||||
%s
|
||||
%c
|
||||
%d
|
||||
%e
|
||||
%f
|
||||
%g
|
||||
|
||||
==== 把LISP函数转化为Emacs命令 ====
|
||||
上述的函数有一个问题:在执行后,光标会移动到缓冲区的末尾。这是LISP命令普遍存在的问题,解决的方法是用save-exeurion函数:
|
||||
(save-excursion
|
||||
statement-block)
|
||||
用这个函数后,语句块中的语句被执行时引起的光标移动在Emacs的内部进行,不会显示在屏幕上。在执行完毕后,插入点和文本块标记将出现在原先的位置。save-excursion函数的返回值是语句块中最后一条语句的返回值。
|
||||
|
||||
在解决了光标移动问题后,还要解决函数的登记问题:必须先对函数进行注册,然后才能在LISP交互式模式中使用。
|
||||
(interactive "prompt-string")
|
||||
这条语句必须是函数里的第一条语句,也就是跟在defun和文档字符串行后面。interactive函数的作用时把函数注册为Emacs的一个命令,这样在执行他时,Emacs会提示用户输入你在defun语法里声明的参数,这个函数的提示字符串是可选的。interactive是按照提示字符串中子字符串先后顺序为函数参数提供值的。
|
||||
|
||||
注意提示字符串有特殊要求,你必须为每一个你想提示用户输入的参数准备一个提示字符串的子串,子字符串用\n字符分割,每个子字符串的第一个字符必须是一个用来表示该参数类型的代码。
|
||||
参数类型代码:
|
||||
b 一个现有编辑缓冲区名字
|
||||
e 事件:鼠标动作或功能键动作
|
||||
f 现有文件名
|
||||
n 数字(整数)
|
||||
s 字符串
|
||||
B 一个可能不存在的缓冲区名字
|
||||
F 一个可能不存在的文件名字
|
||||
S 符号
|
||||
interactive函数还有一个选项r,当以交互式调用函数时,自动把函数的两个参数值设为point和mark函数的返回值。
|
||||
|
||||
文档字符串时用户发出describe-function等在线帮助命令时将会看到的帮助信息,他们时可选的,长度时任意多行,传统上其第一行应是对命令功能进行介绍的一个完整而精炼的句子。
|
||||
|
||||
===== LISP语言基础函数 =====
|
||||
基础函数时用来打造自己工作函数的建筑材料,LISP在其它程序设计语言使用操作符(用于算术、比较、逻辑运算)的地方使用的是函数。
|
||||
|
||||
==== 算术运算: ====
|
||||
+ 、- 、*、/、%、1+、1-、max、min
|
||||
|
||||
|
||||
==== 关系运算: ====
|
||||
>、>=、< 、<=、/=
|
||||
= 用于数字和字符
|
||||
equal 等于,用于字符串和其它复杂的字符串
|
||||
|
||||
|
||||
==== 逻辑运算 ====
|
||||
and or not
|
||||
除 1+ 1- %外其它的算术函数都可以有任意个参数,逻辑运算也是如此。算术运算只有在其参数中至少有一个是浮点数时才返回浮点值。
|
||||
|
||||
==== 语句块 ====
|
||||
LISP语言中可以定义语句块的两个函数是:progn和let。
|
||||
progn是最基础的:
|
||||
(progn
|
||||
statemetn-block)
|
||||
progn是个让一个语句块看起来就像是一条语句的简单方法,与C中的花括号类似,返回值时语句块中最后一条语句的值。progn特别适合向if这样的控制
|
||||
结构中,因为这些控制结果不像while那样允许使用语句块。
|
||||
let函数的变体:
|
||||
(let (var1 var2 ...)
|
||||
statement-block)
|
||||
上面没有使用(var value)这样的列表,它只是一个由变量名组成的列表,所有的变量被初始化为nil。在有些场合如
|
||||
let在定义变量时需要用某些局部变量的值来计算另一些局部变量的值,这需要用let的另一种形式 let*.
|
||||
|
||||
==== 控制结构 ====
|
||||
|
||||
LISP提供了三种控制结构:while、if、cond。
|
||||
|
||||
if函数的语法为:
|
||||
(if condition
|
||||
true-case
|
||||
false-block)
|
||||
true-case必须是单独的一条语句,而false-block则是一个语句块可以省略。
|
||||
|
||||
cond相当于C中的case或switch语句,语法为:
|
||||
(cond
|
||||
(condition1
|
||||
statment-block)
|
||||
(condition2
|
||||
statment-block2)
|
||||
....)
|
||||
|
||||
|
||||
==== Emacs内部函数 ====
|
||||
内部函数是指许多现成的Emacs函数和一些自己开发的函数,它们大部分与字符串和编辑缓冲区中的文本处理工作有关。
|
||||
与缓冲区和文本有关的函数:
|
||||
函数名 返回值或执行的动作
|
||||
point 光标的位置
|
||||
mark 文本块标记的字符位置
|
||||
|
||||
point-min 最小字符位置(通常是1)
|
||||
point-max 最大字符位置,通常为缓冲区的长度
|
||||
|
||||
bolp 光标是否位于行首
|
||||
eolp 光标是否位于行尾
|
||||
bobp 光标是否位于缓冲区开始
|
||||
eobp 光标是否位于缓冲区末尾
|
||||
|
||||
insert 把任意个数的参数(字符或字符串)插入到光标之后
|
||||
|
||||
==== 正则表达式 ====
|
||||
|
||||
如果要对正则表达式中的元字符进行转义,就必须在它的前面加上两个连续的反斜线字符如\\*匹配一个星号字符,这里使用两个星号的原因与Emacs LISP
|
||||
读取和解码字符串的操作方法有关,在读取字符串到一个LISP程序里时Emacs会把两个斜线转换为单个反斜线字符。但是把把正则表达式字符串交互式地
|
||||
输入到用户级命令时只有一个斜线就够了。
|
||||
|
||||
正则表达式操作符汇总:
|
||||
操作符 作用
|
||||
. 匹配任意一个字符
|
||||
* 匹配前面的字符或字符组零次或多次
|
||||
+ ...一次或多次
|
||||
? 零次或一次
|
||||
[...]
|
||||
\\( \\)
|
||||
\\| 匹配前后的子表达式,其作用范围是直到正则表达式开头、结尾、一个\\( 、一个\\)或另一个\\|^
|
||||
^
|
||||
$
|
||||
\n
|
||||
\t
|
||||
\\<
|
||||
\\>
|
||||
\\N
|
||||
|
||||
==== 使用正着表达式的函数 ====
|
||||
用户级命令,他们都可以用在LISP代码中:
|
||||
re-search-forward
|
||||
re-search-backward
|
||||
replace-regexp
|
||||
query-replace-regexp
|
||||
isearch-forward-regexp
|
||||
isearch-backward-regexp
|
||||
|
||||
还有一些不能作为用户级命令使用但可以出现在LISP代码中的函数:
|
||||
looking-at 输入参数为正则表达式,查看光标后面的文本是否匹配该表达式,若是会截取\\(和\\)之间的片段并保持工艺后使用。
|
||||
string-match 参数为一个正则表达式和一个字符串,返回匹配正则表达式的首字符在字符串中的索引
|
||||
match-beginning
|
||||
match-end 用来检索被保存起来的字符串片段,返回的时字符串片段在文本缓冲区的起始点和结束点。
|
||||
buffer-string 把整个缓冲区作为一个字符串返回
|
||||
buffer-substring 两个参数指定子字符串在缓冲区的起始和结束位置,把截取的子字符串返回。
|
||||
|
||||
===== 主编辑模式程序设计实例 =====
|
||||
|
||||
==== 主编辑模式的组建 ====
|
||||
符号 实现这个主编辑模式的函数名称
|
||||
名字 显示在状态行括号的名称
|
||||
局部键位图 用来定义这个主编辑模式里各种命令的按键绑定
|
||||
变量和常数 为实现这个编辑模式,LISP代码使用的一些局部变量和局部常数
|
||||
专用编辑缓冲区 这个主编辑模式下有特殊用途的编辑缓冲区
|
||||
|
||||
=== 一、设置主编辑模式的符号 ===
|
||||
(setq major-mode 'mode-name)
|
||||
|
||||
=== 二、设置主编辑模式的名字 ===
|
||||
(setq mode-name "stings")
|
||||
|
||||
=== 三、局部键位映射表 ===
|
||||
|
||||
== 1.定义映射表 ==
|
||||
(setq tmpkeymap (make-keymap)) ;; set up the keymap var
|
||||
也可以使用make-keymap的特殊形式:如果需要绑定的按键数目不大,使用make-sparse-keymap更有效。
|
||||
|
||||
== 2.把映射表设为主编辑模式的局部键位映射表 ==
|
||||
(use-local-map tmpkeymap)
|
||||
|
||||
=== 四:定义和设置局部变量 ===
|
||||
|
||||
== 1.定义变量 ==
|
||||
有几种定义变量的方法,比如setq给参数赋值或用let给语句块定义并初始化参数,更正规的方法是使用defvar函数。它允许程序员将变量的资料集成到
|
||||
C-h v等在线帮助功能中。defvar函数的语法是:
|
||||
(defvar varname initial-value "description of the variable")
|
||||
defvar还有一个变体叫做defconst用来定义常数。
|
||||
|
||||
== 2/设置局部变量 ==
|
||||
把变量设为主编辑模式的局部变量。
|
||||
(make-local-variable 'variable-name) ;;注意使用的是变量名而非其值
|
||||
|
||||
==== 五:专用特殊缓冲区 ====
|
||||
这些缓冲区与任何文件都没有关联关系,要想在新窗口创建一个新的编辑缓冲区可以使用pop-to-buffer函数:
|
||||
(pop-to-buffer "*Calc*")
|
||||
其它的变体:
|
||||
switch-to-buffer 与命令C-x b相同
|
||||
set-buffer 将编辑缓冲区指定为文本编辑缓冲区使用
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
168
Zim/Utils/emacs/Lisp.txt
Normal file
@@ -0,0 +1,168 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-03T17:27:02+08:00
|
||||
|
||||
====== Lisp ======
|
||||
Created Sunday 03 April 2011
|
||||
针对Emacs中文本编辑的编程简介
|
||||
2010年3月6日 ahei 发表评论 阅读评论
|
||||
http://emacser.com/edit-in-elisp.htm
|
||||
|
||||
|
||||
Elisp是Emacs下的Lisp方言,而Emacs是一款编辑器。那么针对于Emacs,Lisp要做的很重要一部分工作当然就是对编辑的自动化支持。比如移动鼠标,输入句子,查找替换,代码高亮等等,简单地说,就是为更好更方便地支持文本编辑提供支持。而把这些函数都重合起来,就起成了Emacs mode。如我们常用的C++ mode,python mode。还有之前我一直在介绍的org-mode等,都是由Elisp拼成的。
|
||||
|
||||
学习Elisp,可以满足对Emacs进行定制的需求,你可以把想要的功能写在.el文件里面,让Emacs来调用。一方面可以实现一些简单的轻量级的功能,而不需要为此寻找和安装一个完整的mode。另一方面,可以修改现有的mode,使得更符合自己的习惯。这符合开源的作法,不爽即改。
|
||||
Elisp函数的简单例子
|
||||
|
||||
===== 光标位置 =====
|
||||
|
||||
;; 返回当前光标的位置
|
||||
(point)
|
||||
;; region的头跟尾
|
||||
(region-beginning)
|
||||
(region-end)
|
||||
;; 最大光标位置(即文件尾),elisp还提供最小光标位置(point-min),不过我觉得那应该都是1吧。
|
||||
(point-max)
|
||||
;; 返回buffer结尾的绝对位置,无视narrow-to-region
|
||||
(buffer-end 1)
|
||||
|
||||
===== 移动光标和搜索 =====
|
||||
|
||||
|
||||
;移动光标到392
|
||||
(goto-char 392)
|
||||
|
||||
; 向前/向后移动n字符
|
||||
(forward-char n)
|
||||
(backward-char n)
|
||||
|
||||
; 跳过所有\n\t,即把光标移动第一个不是换行或制表符那里
|
||||
; 返回移动的字符数
|
||||
(skip-chars-forward "\n\t")
|
||||
(skip-chars-backward "\n\t")
|
||||
|
||||
; 移动光标到myStr后面,向前和向后
|
||||
; 返回新的光标位置
|
||||
(search-forward myStr)
|
||||
(search-backward myStr)
|
||||
|
||||
; 同上,但是参数是正则表达式,myRegex
|
||||
; 返回新的光标位置
|
||||
(re-search-forward myRegex)
|
||||
(re-search-backward myRegex)
|
||||
|
||||
|
||||
===== 文本编辑 =====
|
||||
|
||||
|
||||
; 删除光标后的九个字符
|
||||
(delete-char 9)
|
||||
|
||||
; 删除选中的两点之前的文本
|
||||
(delete-region mystartpos myendpos)
|
||||
|
||||
; 在当前光标位置插入一字符串
|
||||
(insert "Forza Inter")
|
||||
|
||||
; 从buffer中获得一个字符串并赋给mystr
|
||||
(setq Mystr (buffer-substring mystartpos myendpos))
|
||||
|
||||
; 改变字符大小写
|
||||
;这个例子是指当前光标之前的20个字符
|
||||
(rapitalize-region (- (point) 20) (point))
|
||||
|
||||
|
||||
===== 字符串 =====
|
||||
|
||||
; 长度
|
||||
(length "abc") ; returns 3
|
||||
|
||||
; 获取一个子串
|
||||
(substring myStr startIndex endIndex)
|
||||
|
||||
; 替换,以正则方式
|
||||
(replace-regexp-in-string myRegex myReplacement myStr)
|
||||
|
||||
|
||||
===== Buffers =====
|
||||
|
||||
|
||||
|
||||
; 当前buffer的名字
|
||||
(buffer-name)
|
||||
|
||||
; 文件名(全路径)
|
||||
(buffer-file-name)
|
||||
|
||||
; 设定一个buffer名
|
||||
(set-buffer myBufferName)
|
||||
|
||||
; 保存
|
||||
(save-buffer)
|
||||
|
||||
; 关闭指定的buffer
|
||||
(kill-buffer myBuffName)
|
||||
|
||||
; 关闭当前buffer
|
||||
(kill-this-buffer)
|
||||
|
||||
; 临时指定一个buffer作为当前buffer
|
||||
(with-current-buffer myBuffer
|
||||
;; do something here ...
|
||||
)
|
||||
|
||||
===== Files =====
|
||||
|
||||
|
||||
; 打开一个文件
|
||||
(find-file myPath)
|
||||
|
||||
; 另存
|
||||
; 会关闭当前的buffer,打开另存好的文件
|
||||
(write-file myPath)
|
||||
|
||||
; 把一个文件内容插入到当前位置
|
||||
(insert-file-contents myPath)
|
||||
|
||||
; 将选中的评论文本加到某个文件后面
|
||||
(append-to-file myStartPos myEndPos myPath)
|
||||
|
||||
; 重命名
|
||||
(rename-file fileName newName)
|
||||
|
||||
; 复制
|
||||
(copy-file oldName newName)
|
||||
|
||||
; 删除
|
||||
(delete-file fileName)
|
||||
|
||||
; 获取路径
|
||||
(file-name-directory myFullPath)
|
||||
|
||||
; 获取文件名(不含路径)
|
||||
(file-name-nondirectory myFullPath)
|
||||
|
||||
; 得到文件名后缀
|
||||
(file-name-extension myFileName)
|
||||
|
||||
; 获得不含后缀的文件名。
|
||||
(file-name-sans-extension "abc.htm")
|
||||
|
||||
|
||||
===== 简单的例子 =====
|
||||
|
||||
|
||||
(defun insert-p-tag ()
|
||||
"Insert <p></p> at cursor point."
|
||||
(interactive)
|
||||
(insert "<p></p>")
|
||||
(backward-char 4))
|
||||
|
||||
在当前光标处插入一个p tag。做法是插放一个串,然后将光标移回4位。
|
||||
编写一个mode
|
||||
|
||||
理论上来讲,知道上面这些东西,你就有能力编写一个mode了。但是,编写mode毕竟是一个复杂的工作,需要编写者对elisp编程具有”hello world”以上很多级的熟练度。
|
||||
|
||||
在李杀网,作者有一个系列文章来讨论如何为一个编程语言编写mode。
|
||||
|
||||
The End. Have fun!
|
||||
262
Zim/Utils/emacs/Misc.txt
Normal file
@@ -0,0 +1,262 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-05T22:03:11+08:00
|
||||
|
||||
====== Misc ======
|
||||
Created Tuesday 05 April 2011
|
||||
|
||||
gccsense也是auto-complete的补全引擎而已.语法检查用flymake,很强悍,DEA中有配置
|
||||
安装yasnippet
|
||||
安装elib
|
||||
安装cedet
|
||||
安装ECB
|
||||
安装Cscope
|
||||
配置tabbar
|
||||
company-mode配置
|
||||
安装auto-complete
|
||||
配置gcc-code-assist
|
||||
配置Doxymacs
|
||||
|
||||
emacs的自动补齐(智能感应) 收藏
|
||||
在编写代码时,自动补齐(成员函数变量,以及……)能提高很大的效率,emacs的自动补齐方法有很多种,我参考了很多其他网友的文章,简单总结了下,希望其他网友不要怪罪我哈,呵呵,我希望把我的学习过程记录下来,能对其他网友有所帮助.以下是几种不同的方法(也可以一块用哈)
|
||||
1. Emacs 自带的hippie-expand (参考的是王垠的)
|
||||
hippie-expand是 Emacs 自带的功能,
|
||||
把M-/ 绑定到 hippie-expand,在.emacs文件中加入
|
||||
;;绑定按键
|
||||
(global-set-key [(meta ?/)] 'hippie-expand)
|
||||
|
||||
hippie-expand 的补全方式。它是一个优先列表, hippie-expand 会优先使用表最前面的函数来补全。通常的设置是:
|
||||
|
||||
(setq hippie-expand-try-functions-list
|
||||
'(try-expand-dabbrev
|
||||
try-expand-dabbrev-visible
|
||||
try-expand-dabbrev-all-buffers
|
||||
try-expand-dabbrev-from-kill
|
||||
try-complete-file-name-partially
|
||||
try-complete-file-name
|
||||
try-expand-all-abbrevs
|
||||
try-expand-list
|
||||
try-expand-line
|
||||
try-complete-lisp-symbol-partially
|
||||
try-complete-lisp-symbol))
|
||||
首先使用当前的buffer补全,如果找不到,就到别的可见的窗口里寻找,
|
||||
如果还找不到,那么到所有打开的buffer去找,如果还……那么到kill-ring里,
|
||||
到文件名,到简称列表里,到list,…… 当前使用的匹配方式会在 echo 区域
|
||||
显示.
|
||||
确实是非常好用,基本上我M-/就能到达我想要的了.
|
||||
|
||||
2 采用etags
|
||||
etags能像cscope那样,在代码里跳来跳去,比如查找函数,变量等,它还能够自动补齐代码.
|
||||
1),先生成etags文件
|
||||
find . /usr/include/ -name "*.c" -or -name "*.cpp" -or -name "*.hpp" -or -name "*.h" |xargs etags --members --language=c++
|
||||
2).配置.emacs
|
||||
(setq tags-file-name "~/TAGS")
|
||||
3),使用
|
||||
在emacs中,M-tab 就可以自动补齐了,不过有时候还是不是很好用.
|
||||
M-. 查找一个tag,比如函数定义类型定义等。
|
||||
C-u M-. 查找下一个tag的位置
|
||||
M-* 回到上一次运行M-.前的光标位置。 M-TAB 自动补齐函数名。
|
||||
|
||||
3 采用cedet包
|
||||
1)下载cedet
|
||||
网址是 http://cedet.sourceforge.net/
|
||||
2)编译
|
||||
tar -zxf cedet-1.0pre3.tar.gz
|
||||
cd cedet-1.0pre3
|
||||
make
|
||||
如果make不成功的话,就看看那个说明吧
|
||||
3)配置
|
||||
查看emacs的配置文件在哪里
|
||||
whereis emacs
|
||||
拷贝编译好了的cedet
|
||||
cp -r cedet-1.0pre3 /usr/share/emacs/
|
||||
查看是否有我们需要的那个文件
|
||||
ls /usr/share/emacs/cedet-1.0pre3/common/cedet.el
|
||||
|
||||
配置.emacs文件,在.emacs文件中加入
|
||||
;;;;;;;;;;cedet
|
||||
(load-file "/usr/share/emacs/cedet-1.0pre3/common/cedet.el")
|
||||
|
||||
;;设置检索范围
|
||||
(setq semanticdb-project-roots
|
||||
(list
|
||||
(expand-file-name "/")));;可以设置为项目的顶级目录
|
||||
|
||||
;;绑定按键,ctr+tab,以下三种,任意选择一个,我喜欢第二个
|
||||
;;(global-set-key [(control tab)] 'senator-complete-symbol);
|
||||
(global-set-key [(control tab)] ' senator-completion-menu-popup)
|
||||
;; (global-set-key [(control tab)] 'semantic-ia-complete-symbol-menu)
|
||||
|
||||
4)使用
|
||||
在一个未输入完成的函数上尝试下ctr+tab键
|
||||
看看效果吧:
|
||||
|
||||
|
||||
emacs auto-complete 收藏
|
||||
|
||||
晚上在家写自己的网游服务端底层库,休息时在网上闲逛,无意中发现一篇介绍emacs auto-complete的文章,正是自己想要的东西。比hippie-expand使用更方便,快捷。于是便下载下来,配置成功。另补充原文没有详细讲解的二点:
|
||||
|
||||
生成etags:在工程目录下执行 find -name "*.h" -or -name "*.cpp" -or -name "*.c" |xargs etags --members --language=c++
|
||||
|
||||
使用etags:M-x visit-tags-table,然后选择要使用的tag文件即可。
|
||||
|
||||
Emacs中使用Cscope 收藏
|
||||
在emacs中使用cscope,在preServer下有三个目录,其中含有.h或.cpp文件。
|
||||
|
||||
第一步:在preServer下执行find ./ -name *.[hc]'*'> cscope.files,其作用是将当前目录下.h和.cpp 文件列表导入cscope.files。
|
||||
第二步:cscope -b,其作用是生成符号列表文件cscope.out。
|
||||
第三步:emacs中一般自动支持cscope,先设定初始索引目录,一般是当前根目录。
|
||||
|
||||
|
||||
;; -*-mode:lisp-interaction-*- -*- coding: gbk-dos -*-
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 外观显示 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;禁用启动画面
|
||||
(setq inhibit-startup-message t)
|
||||
|
||||
;; *scratch* buffer的提示信息
|
||||
(setq initial-scratch-message "")
|
||||
|
||||
;; 字体 可 "Monaco-11" 来改字号
|
||||
(set-default-font "Monaco-12")
|
||||
|
||||
;; 设置中文字体
|
||||
(set-fontset-font "fontset-default"
|
||||
'gb18030 '("微软雅黑" . "unicode-bmp"))
|
||||
|
||||
;; Frame 中的字体添加
|
||||
(add-to-list 'default-frame-alist '(font . "Monaco-12"))
|
||||
|
||||
;; 调出 windows 的字体对话框, 奇怪的有些字体安装在系统了却没有出现, 在 notepad 中可以看到
|
||||
;; (w32-select-font nil t)
|
||||
|
||||
;;尺寸
|
||||
(setq initial-frame-alist '( (width . 80) (height . 25)))
|
||||
|
||||
;;标题格式, "文件名 @ 全路径文件名"
|
||||
(setq frame-title-format '("%b @ " buffer-file-name))
|
||||
|
||||
;;取消显示工具栏
|
||||
(tool-bar-mode nil)
|
||||
|
||||
;; 取消显示菜单栏
|
||||
(menu-bar-mode nil)
|
||||
|
||||
;;去掉滚动条, 鼠标滚轮代替
|
||||
(set-scroll-bar-mode nil)
|
||||
|
||||
;;底栏显示列号
|
||||
(setq column-number-mode t)
|
||||
|
||||
;;显示括号匹配
|
||||
(show-paren-mode t)
|
||||
|
||||
;;显示日期
|
||||
(setq display-time-day-and-date t)
|
||||
;;显示时间
|
||||
(display-time)
|
||||
;;时间为24小时制
|
||||
(setq display-time-24hr-format t)
|
||||
;;时间显示包括日期和具体时间
|
||||
(setq display-time-day-and-date t)
|
||||
;;时间栏旁边启动邮件设置
|
||||
(setq display-time-use-mail-icon t)
|
||||
;;时间的变化频率
|
||||
(setq display-time-interval 10)
|
||||
|
||||
;;光标靠近鼠标指针时,让鼠标指针自动让开,别挡住视线。
|
||||
(mouse-avoidance-mode 'animate)
|
||||
|
||||
;;指针不闪,不恍花眼睛。
|
||||
(blink-cursor-mode -1)
|
||||
(transient-mark-mode 1)
|
||||
|
||||
;; 显示行号切换
|
||||
(global-set-key [C-f6] 'global-linum-mode)
|
||||
|
||||
;;语法加亮
|
||||
(global-font-lock-mode t)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 全局设定 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;y/n替代yes/no
|
||||
(fset 'yes-or-no-p 'y-or-n-p)
|
||||
|
||||
;;设置粘贴缓冲条目数量
|
||||
(setq kill-ring-max 200)
|
||||
|
||||
;;递归使用minibuffer
|
||||
(setq enable-recursive-minibuffers t)
|
||||
|
||||
;;支持外部程序粘贴
|
||||
(setq x-select-enable-clipboard t)
|
||||
|
||||
;; 默认 80 列自动换行, 需要 M-x auto-fill-mode 模式下
|
||||
(setq default-fill-column 80)
|
||||
|
||||
;;取消错误铃,闪屏
|
||||
(setq visible-bell t)
|
||||
|
||||
;;设置默认工作目录
|
||||
(setq default-directory "~/work/")
|
||||
|
||||
;;默认为text模式
|
||||
(setq default-major-mode 'text-mode)
|
||||
|
||||
;; 我的信息
|
||||
(setq user-full-name "xxxxx")
|
||||
(setq user-mail-address "xxxxx@gmail.com")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 我的插件目录导入 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; 添加目录和二级子目录
|
||||
(defun add-to-load-path (load-path-name)
|
||||
(let (default-directory-old default-directory)
|
||||
(progn (cd load-path-name)
|
||||
(normal-top-level-add-subdirs-to-load-path))))
|
||||
|
||||
(add-to-load-path "~/etc/emacs23/site-lisp")
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 风格 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(require 'color-theme)
|
||||
(color-theme-initialize)
|
||||
(color-theme-arjen)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Unicad ;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
(require 'unicad)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; htmlize
|
||||
;;;; 网上下载的 htmlize 会使用报错: invalid face, 解决方法:
|
||||
;;;; 将下面一行:
|
||||
;;;; for f = face then (face-attribute f :inherit)
|
||||
;;;; 改为
|
||||
;;;; for f = face then (or (face-attribute f :inherit) 'unspecified)
|
||||
(require 'htmlize)
|
||||
(setq org-publish-project-alist
|
||||
'(("orgfile"
|
||||
:base-directory "~/work/org/source"
|
||||
:publishing-directory "~/work/org/publish"
|
||||
:base-extension "org"
|
||||
:section-numbers nil
|
||||
:auto-index t
|
||||
:headline-levels 3
|
||||
:publishing-function org-publish-org-to-html
|
||||
:style "<link rel=\"stylesheet\" href=\"../other/mystyle.css\" type=\"text/css\">")
|
||||
|
||||
("images"
|
||||
:base-directory "~/work/org/source/image"
|
||||
:base-extension "jpg\\|gif\\|png\\|bmp"
|
||||
:publishing-directory "~/work/org/publish/image"
|
||||
:publishing-function org-publish-attachment)
|
||||
|
||||
("other"
|
||||
:base-directory "~/work/org/source/other"
|
||||
:base-extension "css\\|el"
|
||||
:publishing-directory "~/work/org/publish/other"
|
||||
:publishing-function org-publish-attachment
|
||||
|
||||
("website" :components ("orgfile" "images")))))
|
||||
|
||||
|
||||
;; org 自动换行
|
||||
(add-hook 'org-mode-hook
|
||||
(lambda () (setq truncate-lines nil)))
|
||||
|
||||
129
Zim/Utils/emacs/dired.txt
Normal file
@@ -0,0 +1,129 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-08T17:08:50+08:00
|
||||
|
||||
====== Emacs -- 强大的文件管理器 ======
|
||||
|
||||
dired 是 Emacs 自带的文件管理器,操作非常方便,再加上一些扩展之后无疑是一个理想的文件管理器。看看这里来了解如何增强你的 dired 。
|
||||
|
||||
===== Mark & Flag =====
|
||||
|
||||
dired 最方便的一点就是可以**对许多文件进行标记,并进行批量操作**。标记的方法有很多,最普通的标记就是 __d __为当前文件贴上删除标签,之后可以使用 __x__ 来真正删除所有贴上删除标签的文件。
|
||||
dired 还提供了许多预定义的方便的标记操作(当使用__ C-u 传递一个前缀参数时,他们执行相反操作__,即去掉标记),例如:
|
||||
|
||||
通常这些命令可以方便地帮你清理垃圾,如果还不满意,可以使用__ % d __REGEXP <RET> 来输入自己的正则表达式,匹配到的文件会被贴上删除标签。
|
||||
|
||||
当然,能用的标签并不止是 __D (即删除标签)__,几乎任何一个字符都可以使用(但需要通过转换,默认的为D和*标签),不过__最常用的还是 *__ , m 命令即是以 * 标记当前文件。同样,dired 提供了很多方便的标记操作(这些命令在传递一个前缀参数的时候都会执行相反的操作,例如 C-u * * 会去掉所有可执行文件的标记):
|
||||
|
||||
dired 可以使用更多的字符进行标记,只是没有提供相应的快捷键操作而已,你可以先以 * 标记,然后使用 * c OLD-MARKCHAR NEW-MARKCHAR 来把 * 标记变换成其他标记,几乎任何字符(当然不包括中文这种多字节的字符)都可以作为标记,不过空格被特殊对待,用于表示所有未标记的文件。
|
||||
|
||||
===== 例子 =====
|
||||
|
||||
列举了这么多命令,多少有些枯燥,我们来把当前目录下的所有备份文件移动到 ~/backup 目录下。假设当前目录已经有一些文件被你以 D 标记,但是暂时还不想删除:
|
||||
|
||||
选择个临时标记,比如 t ,只要保证当前 buffer 里面没有已经存在的这种标记就行了。
|
||||
*c D t 把当前所有 D 标签换为 t 标签。
|
||||
~ 以 D 标记所有备份文件。
|
||||
*c D * 把 D 标签换为 * 标签。
|
||||
R ~/backup <RET> 来把所有标记为 * 的文件移动到 ~/backup 目录里面。
|
||||
*c t D 恢复原来的 D 标记。
|
||||
|
||||
当然这要假设你原来没有设定其他的 * 标记,要不然你也可以再添加一个临时标记。总之操作和清晰也很方便,感觉像在汇编语言里面使用寄存器一样,__大多数批量操作都是针对 * 标记的,所以对某个标记操作之前需要把他先转换为 * 标记。__
|
||||
|
||||
===== 文件操作 =====
|
||||
|
||||
dired 内建了很多文件操作,对于操作的文件有一个统一的约定,按照顺序是:
|
||||
|
||||
__如果你通过 C-u 传递一个前缀参数 N ,那么它对从当前行开始的 N 行执行操作( N 也可以是负数)。__
|
||||
__ 如果有被标记为 * 的文件,则以这些文件为操作对象。__
|
||||
__ 只对当前光标所在的文件进行操作。__
|
||||
|
||||
这些命令全部__绑定到大写字母__上,记忆也非常方便:
|
||||
|
||||
C 拷贝文件。把 dired-recursive-copies 设为非 nil 的值可以递归拷贝目录,通常我们设定为 top ,这表示对于顶层目录 dired 会先进行询问是否要递归拷贝,而其中的子目录则不再询问。如果嫌询问太麻烦,可以直接设置为 always 。
|
||||
D 删除文件。类似的有一个 dired-recursive-deletes 变量可以控制递归删除。
|
||||
R 重命名文件,也就是移动文件。
|
||||
H 创建硬链接。
|
||||
S 创建软链接。
|
||||
M 修改权限位,即 shell 里面的 chmod 命令。
|
||||
G 修改文件所属的组。
|
||||
O 修改文件的所有者。
|
||||
T 修改文件的修改时间,类似于 shell 命令 touch 。
|
||||
P 打印文件。
|
||||
Z 压缩或解压文件。
|
||||
L 把 Elisp 文件加载进 Emacs 。
|
||||
B 对 Elisp 文件进行 Byte compile 。
|
||||
__ A 对文件内容__进行正则表达式搜索,搜索会在第一个匹配的地方停下,然后可以使用 __M-, __搜索下一个匹配。
|
||||
Q 对文件内容进行交互式的正则表达式__替换__。
|
||||
!command 对文件执行shell命令
|
||||
|
||||
===== 单字符命令 =====
|
||||
|
||||
__#__ 为所有自动保存的文件(通常是文件名开始和结尾都是 # 的文件)贴上删除标签。
|
||||
__~__ 为所有备份文件(即文件名以 ~ 结尾的文件,Emacs 和 vi 等编辑器默认情况下都会产生这样的文件)贴上删除标签。
|
||||
__&__ 为“垃圾文件”(看 dired-garbage-files-regexp 的值可以知道 dired 把哪些文件当作了垃圾文件)贴上删除标签。
|
||||
以上命令的标记为D
|
||||
a 在当前buffer打开目录(默认是在新的buffer打开目录)
|
||||
i 在当前buffer尾部打开目录,并设置标记
|
||||
k 隐藏标记为*的文件
|
||||
o 在新buffer中打开当前文件,并将光标移到其中
|
||||
q 关闭当前窗口(不是文件编辑窗口)
|
||||
n 下移一行
|
||||
p 上移一行
|
||||
空格 下移一行
|
||||
s 将文件按名称或修改时间排序
|
||||
d 将文件标记为删除
|
||||
u取消文件的标记状态
|
||||
U 取消整个文件的标记状态
|
||||
t 交换标记,将已加*与未加*的交换
|
||||
j 跳转到当前目录中一个文件,并设置标记
|
||||
g 现实k隐藏的文件
|
||||
x 执行标记对应的操作
|
||||
v 察看文件内容
|
||||
m 设置标记
|
||||
Break 删除上一行的标记
|
||||
y 察看当前文件类型
|
||||
! 对文件执行shell命令
|
||||
+ 创建目录
|
||||
|
||||
__w 复制文件名,如果通过 C-u 传递一个前缀参数 0 ,则复制决定路径名,如果只是 C-u 则复制相对于 dired 当前目录的相对路径。__
|
||||
I 把当前文件以 info 文档的格式打开。
|
||||
N 把当前文件以 man 格式打开(使用 WoMan)。
|
||||
Y 为所有标记的文件创建一个到指定目录的相对符号连接(即使用相对路径进行引用,而不是绝对路径)。
|
||||
|
||||
|
||||
===== *命令 =====
|
||||
** 标记所有可执行文件
|
||||
*@ 标记所有符号链接文件
|
||||
*/ 标记所有目录文件
|
||||
*s 标记所有文件为*
|
||||
*. 标记具有给定扩展名的文件
|
||||
* % REGEXP <RET>标记所有__文件名__匹配到给定的正则表达式的文件
|
||||
*? MARKCHAR 或 M-<DEL> __去除所有以 MARKCHAR 标记的文件的标记__,如果传递一个前缀参数,则会对每一个文件要求你确认是否去除标记。
|
||||
__* c OLD-MARKCHAR NEW-MARKCHAR__ 把 * 标记变换成其他标记
|
||||
以上命令的标记为*
|
||||
|
||||
===== %命令(一般和正则表达式有关) =====
|
||||
%d REGEXP <RET> 把__文件名__符合正则表达式的文件标记为删除D
|
||||
% m REGEXP <RET> >标记所有__文件名__匹配到给定的正则表达式的文件
|
||||
% g REGEXP <RET> 标记所有__文件 内容__ 匹配到给定的正则表达式的文件
|
||||
正则表达式语法为grep而非egrep
|
||||
|
||||
===== 强大的重命名功能 =====
|
||||
|
||||
dired 有一个文件名转换的理念,所以转换,并不一定是重命名,还可以是复制和创建链接。所以,除了 % u 和 % l 重命名原文件为大写、小写外,一个使用正则表达式进行转换的命令提供了四个选项: __% X 其中 X 可以是 R , C , H 和 S __,分别代表重命名、复制、创建硬链接和创建软链接,他们使用匹配和替换的机制,这有点像 rename 这个程序,例如: % R \.[^.]*$ <RET> .1\& <RET> 给原来的文件名加个标号 1 ,把 foo.txt 变成 foo.1.txt 。
|
||||
|
||||
另外,dired 还有一个叫做 __Wdired__ 的扩展可以直接在 dired 的 buffer 里面编辑文件名来达到重命名的效果。使用 __M-x wdired-change-to-wdired-mode__ 进入编辑模式,这个时候可以直接像编辑普通文本一样编辑文件名,还可以添加路径来实现把文件移动到其他目录(可以通过保存文件的方式来使更改生效)。除了文件名可以编辑以外,其他部分被标记为只读,但是如果把 __wdired-allow-to-change-permissions__ 设为 t 的话,还可以编辑文件的权限位。编辑完成之后使用 C-c C-c 来应用所做的编辑。非常方便。
|
||||
|
||||
===== 排序和过滤 =====
|
||||
|
||||
dired 有方便的排序功能,这里介绍了如何方便地使用排序功能。另外 dired 还有一个 __k__ 用于去掉不想显示出来的文件,它并不删除磁盘上的文件,只是临时从 dired 的 buffer 中去掉他们,__ g __刷新一下它们又会显示出来,这样,首先用强大的标记功能进行标记,然后使用 k 去掉,就实现了过滤的功能。
|
||||
子目录操作
|
||||
|
||||
===== 同时操作当前目录和子目录 =====
|
||||
dired 允许同时操作当前目录和子目录。在 dired-listing-switches 里面加入 R 选项就可以显示子目录,如果只是想临时显示某个子目录的内容,对该目录执行__ i __操作就会把该子目录的内容添加到 dired __当前 buffer 的末尾__并把光标移动到那里,dired 在__移动之前会先设置一个 mark__ ,所以可以使用 C-u C-<SPC> (对于我来说,我把 set-mark-command 绑定到了 M-<SPC> 上,这里自然就是使用 C-u M-<SPC> 了)回到原来的位置。
|
||||
|
||||
|
||||
还有一些方便的功能,我把几个常用的命令列在这里:
|
||||
|
||||
|
||||
139
Zim/Utils/emacs/dired/Dired.txt
Normal file
@@ -0,0 +1,139 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-17T23:11:14+08:00
|
||||
|
||||
====== Dired ======
|
||||
Created Wednesday 17 August 2011
|
||||
http://www.fengyj.net/emacs/Dired.html
|
||||
|
||||
Dired
|
||||
|
||||
在 dired 中移动
|
||||
在 dired 中删除文件(Flags)
|
||||
一次性标记很多文件
|
||||
在Dired中访问文件
|
||||
在Dired中用Mark
|
||||
操作文件
|
||||
在 dired 中使用shell命令
|
||||
dired 中的文件比较
|
||||
|
||||
==== 在 dired 中移动 ====
|
||||
|
||||
C-n,n,<space>向下移动一行。
|
||||
C-p,p,<del>向上移动一行。<del>同时还会去掉之前的标记。
|
||||
j:dired-goto-file,移动到指定目录或文件所在的行。
|
||||
|
||||
==== 在 dired 中删除文件(Flags) ====
|
||||
d:给文件作一个删除标记(flag)。
|
||||
u:删除文件的删除标记。
|
||||
<del>:移动到上一行,然后移除上一行的删除标记。
|
||||
x:执行删除指令。
|
||||
|
||||
被删除标记标记的文件或目录前会有一个 D 标记。
|
||||
一般情况下不能直接删除非空目录,除非变量 dired-recursive-deletes 不为空。
|
||||
|
||||
==== 一次性标记很多文件 ====
|
||||
~:标记所有备份文件,形如“~文件名”的文件。
|
||||
% d REGEXP <REG>o:为符合正则表达式的文件作标记。
|
||||
|
||||
==== 在Dired中访问文件 ====
|
||||
f:直接访问当前行所指示的文件。 <return>,e:和f一样。
|
||||
o:和f相似,但在另一个窗口打开文件,光标移到新窗口。
|
||||
c-o:和f相似,但在另一个窗口打开文件,光标还是在旧窗口。
|
||||
__^__:访问父级目录,相当于移到当前目录的".."行,然后按f键。
|
||||
v:和 f 类似,但是打开的文件是只读的。
|
||||
|
||||
==== 在Dired中用Mark ====
|
||||
|
||||
dired的删除标记叫做 flag,一般的标记则为 mark,dired-mark。
|
||||
|
||||
* mark
|
||||
用*给当前文件作标记。如果提供一个正数作为参数N,则标记从当前文件( 包括当前文件)开始向下的N个文件,如 C-u 3 * m 顺序标记3个文件,如果是负数则向上标记N个文件。
|
||||
* *
|
||||
标记所有可执行文件,如果有个参数,则 unmark 这些可执行文件。
|
||||
* @
|
||||
标记所有 链接 文件,如果有个参数,则 unmark 这些链接文件。
|
||||
* /
|
||||
标记所有目录文件,**除了"."和".."目录**,如果有个参数,则 unmark 这些目录。
|
||||
__* s__
|
||||
标记该目录下的所有文件及目录,除了"."和".."目录。
|
||||
* u
|
||||
删除当前行的标记
|
||||
* <del>
|
||||
移动到上一行,并删除那一行的 mark。
|
||||
U
|
||||
移除当前 dired buffer 中的所有 mark,即当前目录中的所有 mark。
|
||||
__M-}__
|
||||
移动到下一个 marked file。(dired-next-marked-file)
|
||||
M-{
|
||||
移动到上一个 marked file。(dired-prev-marked-file)
|
||||
* t
|
||||
mark 开关,也就是 marked files 在执行完命令后变成 unmarked files,而 unmarked files 变成 marked files。(dired-toggle-files)
|
||||
__* c__ OLD-CHARACTOR NEW-CHARACTOR
|
||||
改变 marked 标记,用 new charactor 的 mark 替换 old character 的 mark,例如: * c * a,则所有星号的标记都会变成字符 a。用该命令可以实现将任意字符作为标记,包括空格字符,空格字符也代表 unmarked files。
|
||||
__* %__ REGEXP <enter>
|
||||
标记所有文件名满足正则表达式的文件。这个和 % d 很类似,% d 是为了给文件作上删除标记。
|
||||
__* g__ % REGEXP
|
||||
如果正则表达式匹配了 dired buffer 中的文件的__内容__,则标记该文件。(dired-mark-files-containing-regexp)
|
||||
C-/
|
||||
dired undo,取消设定的 mark。
|
||||
|
||||
==== 操作文件 ====
|
||||
|
||||
在命令前加入数字参数 N,就会操作以当前光标所在的行为基准,向下连续的N个文件,如果N是负数,则操作反方向的连续N个文件。
|
||||
如果文件被 * 号标记,则操作所有被星号标记的文件。 再者就操作当前行的文件。
|
||||
|
||||
下面是操作dired中文件的命令:
|
||||
|
||||
`C new <ret>'
|
||||
复制特定文件(`dired-do-copy')。类似shell命令 cp,变量 `dired-recursive-copies' 控制是否遍历复制子目录,就像 cp -r,默认情况是 `nil',意味不能复制子目录。
|
||||
`D'
|
||||
删除指定文件(`dired-do-delete')。和shell中的 rm 命令类似。
|
||||
`R NEW <RET>'
|
||||
重命名指定文件(`dired-do-rename')。如果指定的是单个文件,则仅仅完成重命名功能,如果指定的是多个文件,则 NEW 指示的是一个文件夹,命令会把指定的文件剪切到文件夹里,就像shell里的 mv 指令。
|
||||
`H NEW <RET>'
|
||||
制作特定文件的硬链接(`diref-do-hardlink')。和shell命令的 ln 类似。
|
||||
`S NEW <RET>'
|
||||
制作特定文件的符号链接(`dired-do-symlink')。和shell命令的 ln -s 类似。
|
||||
__`M__ MODESPEC <RET>'
|
||||
改变文件的权限(`dired-do-chmod')。
|
||||
`G NEWGROUP <RET>'
|
||||
改变文件所属的组为 NEWGROUP。(`dired-do-chgrp')。
|
||||
`O NEWOWNER <RET>'
|
||||
改变文件的所有者为 NEWOWNER。(`dired-do-chown')。
|
||||
`T TIMESTAMP <RET>'
|
||||
将文件的修改时间调整到当前时间,和shell命令中的 touch 类似(`dired-do-touch')。
|
||||
`P COMMAND <RET>'
|
||||
(`dired-do-print')。
|
||||
__`Z'__
|
||||
压缩特定的文件(`dired-do-compress')。如果文件已经是压缩文件,则Z会给该文件解压缩。
|
||||
`L'
|
||||
装载特定的 Emace Lisp。
|
||||
|
||||
==== 在 dired 中使用shell命令 ====
|
||||
|
||||
dired 的命令 ! 会在 minibuffer 中提示你輸入 shell 命令,用此命令来操作指定的文件。
|
||||
|
||||
有两种方式可以让shell command操作多个文件:
|
||||
|
||||
* 命令行包含两边有空格的星号*
|
||||
如果星号两边为空格,__命令只会执行一次__,* 号会代替当前dired buffer 中__标记__的所有文件名,文件名的顺序即为dired buffer中文件名的顺序。
|
||||
因此,命令 `! tar czvf zip.tar.gz *' 将当前dired buffer 中的所有文件压缩到 *zip.tar.gz* 中。
|
||||
* 如果命令行不包括星号,命令会在__每个文件上执行一次__。
|
||||
例如:`! uudecode <return>'会用uudecode命令依次执行每个文件。
|
||||
* 命令行上有星号,但两边没有空格,这时会将该星号传给shell当作通配符使用。匹配的文件会和标记的文件一起传给命令 如:
|
||||
* wl -l "*.cpp~" * //会将当前目录下的所有以.cpp~结尾的文件与当前标记的所有文件一起传给wl命令。
|
||||
* wl -l "*cpp~" //会将当前目录下的所有以.cpp~结尾的文件与当__前标记的文件一次一个__按先后顺序传给wl命令。
|
||||
* 命令行包括两边为空格的 ? 用指令操作当前文件,当前行的文件名会替代?。例如:
|
||||
! chmod 777 ? <return> 会将当前行的文件的权限改为777。
|
||||
|
||||
! 用命令行执行的指令不会立即改变dired buffer,但可以用g强制刷新 dired buffer。
|
||||
|
||||
==== dired 中的文件比较 ====
|
||||
|
||||
有两个 dierd 命令用 diff 比较特定的文件:
|
||||
|
||||
` = '
|
||||
用当前文件(the file at the point)来比较另外一个文件(the file at the mark),利用的是dired的diff程序(`dired-diff')。用 mark标记的文件不是dired的mark,而是__emacs的标准mark__,用快捷键 C-SPACE或C-@所作的mark。
|
||||
`M-='
|
||||
用当前文件的备份文件于当前文件进行比较。(`dired-backup-diff')。
|
||||
135
Zim/Utils/emacs/dired/Emacs的文件管理器Dired.txt
Normal file
@@ -0,0 +1,135 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-17T23:28:57+08:00
|
||||
|
||||
====== Emacs的文件管理器Dired ======
|
||||
Created Wednesday 17 August 2011
|
||||
|
||||
|
||||
详细的用法说明可以参照Emacs的info文件,这里只是介绍一些常用的功能。
|
||||
|
||||
M-x dired 或者 C-x d,可以进入dired-mode,这样便可以对文件进行操作了,作为一个文件管理器还是挺不错的。
|
||||
|
||||
在.emacs里加入以下语句。
|
||||
|
||||
(setq dired-recursive-deletes t) ; 可以递归的删除目录
|
||||
(setq dired-recursive-copies t) ; 可以递归的进行拷贝
|
||||
(require 'dired-x) ; 有些特殊的功能
|
||||
(global-set-key "/C-x/C-j" 'dired-jump) ; 通过 C-x C-j 跳转到当前目录的 Dired
|
||||
(setq dired-guess-shell-alist-user
|
||||
(list
|
||||
(list "//.chm$" "xchm")
|
||||
(list "//.rm$" "gmplayer")
|
||||
(list "//.rmvb$" "gmplayer")
|
||||
(list "//.avi$" "gmplayer")
|
||||
(list "//.asf$" "gmplayer")
|
||||
(list "//.wmv$" "gmplayer")
|
||||
(list "//.htm$" "w3m")
|
||||
(list "//.html$" "w3m")
|
||||
(list "//.mpg$" "gmplayer")
|
||||
)
|
||||
) ; 设置一些文件的默认打开方式,此功能必须在(require 'dired-x)之后
|
||||
一些常用的命令
|
||||
|
||||
和文件一样打开目录或通过 C-x d 都可以进入目录的 Dired 缓冲中。这里是打开 Dired-x 之后默认的绑定。说明后面[]中的符号的意义:
|
||||
[*] 作用在已标记的所有文件(目录)或光标所在当前文件(目录)上。
|
||||
[p] 用前缀参数表示文件个数,从当前文件开始,正数向下、负数向上。
|
||||
[u] 用前缀参数改变默认行为。对于设置标记的命令一般变为去掉标记。
|
||||
[x] 需要加载 dired-x。
|
||||
查看帮助
|
||||
? 简单帮助
|
||||
h 模式帮助
|
||||
移动光标
|
||||
n, p, SPC 上、下移动光标 [p]
|
||||
C-n, C-p 上、下移动光标 [p]
|
||||
M-{, M-} 已标记的文件之间移动 [p]
|
||||
C-M-p, C-M-n 缓冲中的子目录间移动 [p]
|
||||
<, > 缓冲中的目录行间移动 [p]
|
||||
C-M-u 缓冲中的目录树上移动 [p]
|
||||
M-g 光标移动到某个文件上
|
||||
M-G 光标移动到某个缓冲中的子目录上,(用 i 插入的)
|
||||
标记文件
|
||||
m 标记文件,下移一行 [p]
|
||||
u 去掉标记,下移一行 [p]
|
||||
U 去掉缓冲中所有的标记
|
||||
M-Backspace 去掉缓冲中所有的某个标记,缺省为 * 标记
|
||||
Backspace 并去掉上一行标记,并上移一行 [p]
|
||||
t 标记/未标记互换
|
||||
D 删除所有标记的文件/目录 [*]
|
||||
d 设置“删除标记”(字符D),并且光标下移一行 [p]
|
||||
x 删除用 d 标记的文件/目录
|
||||
~ 将缓冲中备份文件做删除标记 [u]
|
||||
& 没用的文件,做删除标记
|
||||
# 将缓冲中自动保存的文件做删除标记 [u]
|
||||
. 按备份文件版本,将备份文件做删除标记 [u]
|
||||
% g 标记所有“含有”regexp 的文件 [u]
|
||||
* * 标记所有可执行文件 [u]
|
||||
* . 标记所有同扩展名文件 [ux]
|
||||
* / 标记所有目录 [u]
|
||||
* @ 标记所有符号连接 [u]
|
||||
* c 改变标记的符号
|
||||
% d 通过匹配 regexp 标记删除
|
||||
% m 通过匹配 regexp 标记 [u]
|
||||
复制、移动、创建 文件或目录以及连接
|
||||
C-x C-f 创建文件
|
||||
+ 创建目录
|
||||
R 文件的重命名/移动 [p*]
|
||||
C 复制文件 [*]
|
||||
S 创建文件的 Symbol link (绝对路径) [p*]
|
||||
Y 创建文件的 Symbol link (相对路径) [px*]
|
||||
H 创建文件的 Hard link [p*]
|
||||
% C 复制匹配 regexp 的文件 [p*]
|
||||
% S 创建匹配 regexp 的 Symbol link (绝对路径) [p*]
|
||||
% Y 创建匹配 regexp 的 Symbol link (相对路径) [p*]
|
||||
% H 创建匹配 regexp 的 Hark link [p*]
|
||||
修改文件名、属性
|
||||
M 修改文件 rwx 权限属性 [*]
|
||||
G 修改文件 Group 属性 [p*]
|
||||
O 修改文件 Owner 属性 [p*]
|
||||
T 修改文件的时间戳 [p*]
|
||||
% l 文件名逐一改为小写 [p*]
|
||||
% u 文件名逐一改为大写 [p*]
|
||||
% R, % r 重命名/移动匹配 regexp 的文件 [p*]
|
||||
访问文件,目录
|
||||
e, f, RET 打开文件或目录
|
||||
a 打开文件或目录,并替换当前缓冲
|
||||
v 使用 view 模式查看文件,q 退出,有些文件使用外部查看程序调用
|
||||
o 另一个窗口中,打开文件或目录
|
||||
C-o 另一个窗口中,打开文件或目录,但当前窗口不变
|
||||
F 打开(多个)文件 [x*]
|
||||
I 使用 Info 模式查看文件
|
||||
N 使用 man 模式查看文件,若有前缀参数,提示输入处理命令 [ux*]
|
||||
V 使用 RMAIL 模式查看文件 [x]
|
||||
退出
|
||||
^ 访问目录的父目录,若有前缀参数在另外的窗口中打开 [u]
|
||||
q 退出缓冲,若有前缀参数则关闭缓冲 [u]
|
||||
隐藏/刷新缓冲中内容
|
||||
s 互换缓冲中“文件名/时间”排序 [u]
|
||||
C-u s 修改传递给 ls 的参数,即修改每行的内容
|
||||
i 把当前行的子目录插入缓冲中
|
||||
M-o 隐藏/显示部分次要文件,使缓冲更简便,若有前缀参数标记隐藏的文件 [ux]
|
||||
$ 隐藏/显示当前目录中内容 [p]
|
||||
M-$ 隐藏/显示缓冲中所有目录内容
|
||||
k 隐藏文件,按 g 可以再显示出来 [p*]
|
||||
l 刷新缓冲文件 [p*]
|
||||
g 刷新缓冲所有文件
|
||||
C-/, C-_, C-x u dired 模式的 undo
|
||||
其他
|
||||
= 比较文件
|
||||
M-= 文件和备份之间比较,若有前缀参数,提示输入 diff 选项 [u]
|
||||
w 复制文件名到 kill-ring [p*]
|
||||
Z 压缩/解压缩文件 [p*]
|
||||
X 在文件上执行 shell 命令 [p*]
|
||||
B 编译(Emacs Lisp)文件 [p*]
|
||||
L 加载(Emacs Lisp)文件 [p*]
|
||||
y 给出文件类型信息 (通过 file 命令)
|
||||
P 打印文件 [p*]
|
||||
dired-x.el 中的其他有用的函数
|
||||
dired-mark-extension 按后缀标记
|
||||
dired-flag-extension 按后缀标记删除
|
||||
dired-clean-patch 标记删除 patch 文件
|
||||
dired-clean-tex 标记删除 tex 编译文件
|
||||
dired-very-clean-tex 标记删除 tex 编译文件
|
||||
dired-jump 跳转到当前缓冲所在目录
|
||||
dired-jump-other-window 在另一个窗口中跳转到当前缓冲所在目录
|
||||
dired-omit-here-always 在当前目录生成 .dired 文件
|
||||
1935
Zim/Utils/emacs/dot.emacs.txt
Normal file
23
Zim/Utils/emacs/dot.emacs/2.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-05-22T21:32:23+08:00
|
||||
|
||||
====== 2 ======
|
||||
Created Sunday 22 May 2011
|
||||
|
||||
(gnus-agentize)
|
||||
|
||||
(setq smtpmail-default-smtp-server "mail.cc.umanitoba.ca")
|
||||
(setq smtpmail-smtp-server "mail.cc.umanitoba.ca")
|
||||
(setq smtpmail-smtp-service 587)
|
||||
(setq message-send-mail-function 'smtpmail-send-it)
|
||||
(setq send-mail-function 'smtpmail-send-it)
|
||||
(setq gnus-select-method '(nntp "news.cc.umanitoba.ca"))
|
||||
(setq gnus-secondary-select-methods '((nnimap "gmail"
|
||||
(nnimap-address "imap.gmail.com")
|
||||
(nnimap-server-port 993)
|
||||
(nnimap-stream ssl))
|
||||
(nnimap "uofm" (nnimap-address "mail.cc.umanitoba.ca")
|
||||
(nnimap-server-port 993)
|
||||
(nnimap-stream ssl))
|
||||
(nntp "freenews.netfront.net") ))
|
||||
507
Zim/Utils/emacs/effcet-emacs.txt
Normal file
@@ -0,0 +1,507 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-05T22:20:26+08:00
|
||||
|
||||
====== effcet-emacs ======
|
||||
Created Tuesday 05 April 2011
|
||||
http://blog.csdn.net/DelphiNew/archive/2008/01/19/2053676.aspx
|
||||
|
||||
**十个提升你Emacs生产力的高招**
|
||||
|
||||
Emacs是世界上最好的编辑器(真的有很多人这么认为)。不要以为emacs只是在编写程序时很牛X,其实只要你真正精通了emacs,会发现她几乎在所有用到打字的应用(比如写email啦,起草文档啦,写blog啦,写html/xml文件等等等)时都是最牛的。
|
||||
|
||||
本文中所写的招数是面向emacs高级用户(译者看此文时并不是emacs高级用户,同样获益非浅啊)的,你应该熟悉基本的emacs启动编辑操作,你得知道怎么把东东拷到你的.emacs里面,在所拷的东东出现问题时,你得知道怎么调试(或者能找到一个乐于助人的emacs高手也行)。
|
||||
|
||||
这里所列出的招数并非都是对emacs的定制,有些是对你桌面环境的调节,这些调节可以使桌面环境更好地与emacs无缝连接工作。
|
||||
|
||||
要想理解emacs的高效,**关键是要明白她的所有设计都是出于效率考虑的**,这里所说的**效率包括“动作的效益”**。任何一个老练的音乐家都知道“动作的效益”是成为世界级艺术家的关键一环。在演奏时任何多余的动作都是浪费精力而且会产生不良效果。
|
||||
|
||||
使用鼠标基本上可以说是最违背动作效益的行为,因为你得提起你的手...摸着鼠标...摆正方位...可以说鼠标是个极笨重的设备,emacs高手在不得不用一下鼠标的时候,都认为这是一次高速缓冲命中失败(学过微机原理的人可能听得懂这句话吧),大大影响的连贯性和速度。
|
||||
|
||||
相对于emacs高手,图形化IDE用户就好比业余的音乐家,带着些许郁闷地把玩着自己的乐器。一般IDE都又炫又好看的对话框,让你很难与之交互(这句话面向的听众是emacs高手,看过下面的条款6就会明白他说什么了),但是却给新手一些操控的快感。可是咧~这种操控是相当粗糙的,真正的程序员需要的是能给他们更多操控机能的东东。(所以基本上可以说,emacs对真正的程序员来说是世界上最好的编辑器啦)
|
||||
|
||||
IDE还具备重构功能,一般什么多人都爱拿这个来吹,因为重构工具可以自动地帮你整理结构不良的代码。没错,在某些程度上来说。但是偶告诉你个秘密喔:重构工具不懂英文耶(所以更不懂中文啦,55)。重构工具一般只能处理一些特定的文本(前面所说的“某种程度”),当她碰上其它编辑工作时,就无能为力啦。重构工具只能解决一小部分问题,而emacs却几乎能在你进行任何一类编辑时提供一系列条理清晰的操控能力。
|
||||
|
||||
然而,正如我常说的,眼见为实,即便你相信,你也得看到实际效果才心甘。那么接下来,你得对emacs做一个严肃的、深远的、长期的承诺,才能真正精通emacs。**精通emacs的过程包括学习Lisp、定制emacs使她最符合你的设想,随着这一过程的,你会更加地渴望有更多定制、更多的自动化,所以,哪怕你已经精通了emacs,你对她的定制和扩展也不会停息的**。
|
||||
|
||||
所以,你看明白了吧?**emacs可不是一个给懦夫使用的编辑器**,这篇博客文章是给那些下了决心、做了承诺并且想要进一步增强他们对这个优雅的顶级的万古长青的软件的掌握。
|
||||
|
||||
其他的读者或者听众:我想你的Eclipse应该刚好启动完毕了,你可以调头回去忙你自个儿的啦~
|
||||
|
||||
__条款1:把Caps-Lock和Control键互换!__
|
||||
|
||||
在Windows和苹果Mac键盘上,那个Ctrl键居然被远远地放在左下角,而Ctrl对于emacs的使用却是时时刻刻都很重要的,如果你不把Ctrl放到一个更舒服的位置,你就很难成一个emacs艺术大师了。这位置应该与你的基本手位处于同一行,那么,Caps Lock是最佳选择。在很多unix工作站上,这个位置放的就是Ctrl键,原因同上。
|
||||
|
||||
要想在w2000或者XP中实现这个互换,需要修改注册表。从开始菜单中选择“运行”,输入regedit。在左边的树状视图中,找到:
|
||||
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
|
||||
|
||||
XXXXX不用译了。
|
||||
点击 KeyboardLayout 项,使之获得焦点。再从“编辑”菜单中选择新建一个二进制值,命名为 "Scancode Map",它的类型应该显示为 REG_BINARY。
|
||||
|
||||
然后选择这个新建的"Scancode Map"值项,用“编辑”菜单中选择修改二进制值,在二进制编辑对话框中,输入下列数据:
|
||||
0000: 00 00 00 00 00 00 00 00
|
||||
0008: 03 00 00 00 3A 00 1D 00
|
||||
0010: 1D 00 3A 00 00 00 00 00
|
||||
|
||||
选择OK关闭对话框,退出注册表编辑器,注销后重登入,你的caps和ctrl键应该就互换成功了。也可能要重启一次。
|
||||
|
||||
在linux的X-Window中,可以使用xmodmap工具。在你的主目录新建一个名字为.xmodmap的文件,如果已经存在则只需修改。向该文件加入下列内容:
|
||||
!
|
||||
! Swap Caps_Lock and Control_L
|
||||
!
|
||||
remove Lock = Caps_Lock
|
||||
remove Control = Control_L
|
||||
keysym Control_L = Caps_Lock
|
||||
keysym Caps_Lock = Control_L
|
||||
add Lock = Caps_Lock
|
||||
add Control = Control_L
|
||||
保存,再向你的 ~/.bash_profile 文件加入一行:
|
||||
xmodmap ~/.xmodmap
|
||||
|
||||
在Mac OS X(Panther或Jaguar)中,你得安装一个修改过的键盘驱动,这说来有些吓人,但是很有效。
|
||||
这儿有个关于驱动的讨论:
|
||||
http://www.macosxhints.com/article.php?story=20031102032521826
|
||||
如果你用的不是Mac笔记本,好像有一个XML文件可以编辑来实现,可以参考这儿:
|
||||
http://www.eecs.wsu.edu/%7Eschneidj/mac-os-x-10.3.html#swap
|
||||
下面的URL有一条关于在其它系统上实现的信息:
|
||||
http://www.manicai.net/comp/swap-caps-ctrl.html
|
||||
|
||||
__条款2:不用Alt来调用M-x__
|
||||
|
||||
Alt-x是最常用的emacs组合键,每次使用时你都得把左手蜷起来。**任何一个你要做几千次的动作最好应该是流线型的**,所以你最好希望可以用Ctrl键来调用M-x。(要想用Ctrl舒服,你得选把条款1完成了)
|
||||
|
||||
要养成使用Ctrl键习惯的另一个重要原因是:Alt键并不可靠也并,alt-x可能都不能使用。与其为不同的系统设置而头痛,还**不如直接就不使用alt键**,使用一个任何时候都有效的组合键相对来说更加容易且方便。
|
||||
|
||||
我选用的组合键序列是Ctrl-x Ctrl-m。请注意,当你调用一个2键序列,而这两个组合键都使用相同的转义键时,你只需按住转义键(这里指Ctrl),再按其它两个键即可(这里指x和m)。所以现在调用M-x的方法是:按住Ctrl,按x,按m,松开Ctrl。
|
||||
|
||||
将下面的lisp表达式加到你的.emacs文件中,就可以启用Ctrl-x Ctrl-m了:
|
||||
(global-set-key "\C-x\C-m" 'execute-extended-command)
|
||||
(global-set-key "\C-c\C-m" 'execute-extended-command)
|
||||
|
||||
我另加了一行设定Ctrl-c Ctrl-m也调用同一命令,使得这个按键组合**更能容错一些**。如果偶不小心把Ctrl-x按成Ctrl-c,仍然能够成功调用。这两个按键都没有默认的emacs绑定,所以你的设置不会影响到其实的快捷键。
|
||||
|
||||
你应该把这个按键序列练到习惯为止,到时你差不多都不想再用alt-x了。(当然,你还会用到alt键来做其它的事,一会儿就告诉你)
|
||||
|
||||
顺便说一下,如果你想把这招发挥到极致,那在你按Ctrl-x**最好不要用你的无名指来敲x键**。这时我会用左手的食指的敲,因为觉得这样比较习惯,但是你可能会觉得用左手中指会更好一些。这是因为当你用小指去按那个变成Ctrl的Caps-Lock时,你的手并不处于键盘的基本方位。**关键是要使用尽可能少的肢体伸缩,尽可能少的手指动作**。你可以实验出你自己觉得最舒服的方式来。
|
||||
|
||||
__条款 3: 使用 backward-kill-word (向后删一词)而不是 Backspace(向后删一字)__
|
||||
|
||||
**emacs高手一般都尽量避免使用backspace键**,因为它离手的基本方位太远了。如果你经常打错字,但是你的速度又很快,一分钟打50个词以上的话,把整个词删掉重打可比勤勤恳恳地用backspace倒删到你打错的地方再从一半打起要经济实惠得多。
|
||||
|
||||
加入下面的几行到你的.emacs文件中:
|
||||
(global-set-key "\C-w" 'backward-kill-word)
|
||||
(global-set-key "\C-x\C-k" 'kill-region)
|
||||
(global-set-key "\C-c\C-k" 'kill-region)
|
||||
|
||||
|
||||
请注意ctrl-w已经有一个默认绑定kill-region了,这是个相当重要的命令,所以你得把它重新绑定到其它按键序列中去。我用的是Ctrl-x Ctrl-k(然后再加一个容错版的Ctrl-c Ctrl-k)。这样用主要是因为我在以前工作的公司,一个很牛X的emacs高手这么帮偶设的,现在我会的很多emacs技术都是当初这个高手教偶的。重绑定Ctrl-x Ctrl-k意味着你没有了edit-kbd-macro的快捷键,但是这个键你真的不会经常去用,所以不会觉得丢了什么东东的。
|
||||
|
||||
这样做还有一个额外的好处:很多Unix命令行shell都提供类似emacs的命令行编辑按键,而Ctrl-W一般都是backward-kill-word的默认绑定。这样的话,你的习惯就和很多shell一致了。
|
||||
|
||||
你打字越快,这招就越升值。慢慢地你对如何最快更改各种打字错误会培养出一种最适合你自己的感觉。我的手感一般是这样的:
|
||||
|
||||
1.如果我打错一两个字符,而此时我的光标刚好就在错误的旁边,我就用backspace键。
|
||||
|
||||
2.如果错误字符在光标前面15到20个字符左右的地方,那我一般就使用Ctrl-W直接杀回去,然后重新打出这些词来。
|
||||
|
||||
如果错误的字还在更远处,那偶就用**alt-b跳回到错词后面,再做ctrl-b定位到错误的字符处理进行更正**。
|
||||
|
||||
对于比之更远的错误,我会使用快速导航来回到那个位置。条款4讲到一部分这个技术。
|
||||
|
||||
使用ctrl-w绑定backward-kill-word时有件事情你可得小心了:Ctrl-w在很多windows程序中是强行绑定到“关闭窗口”这一操作上的。这一动作没得后悔,在浏览器窗口中,它也不会保存你填写过的表单。也就是说,如果你正在为一个网页填写表单,然后你忽地想用ctrl-w来更正一个错误,咔嘣!--完咧~在你那好用的OLE版M$ windows上,你的所有工作都白费了。目前我还不知道怎么覆盖掉这个可怕的行为,如果你知道怎么做,麻烦你考虑我一下。
|
||||
|
||||
__条款4:使用递增式搜索来进行快速导航__
|
||||
|
||||
**知道如何高效地移动光标是成为emacs高手的关键**。IDE用户把他们大部份的时间花在摸索鼠标上了,根本没有想过如何用其它方法来实现光标导航,却不知道自己的方法是多么的低效。在一个高手的手中,emacs是世界上最高效的文本编辑工具,主要是因为她可以让你不用鼠标做到几乎所有的事情。
|
||||
|
||||
emacs高手总是**设法让他们的会话窗口越高越好**,最好是能垂直地填满整个屏幕--因为垂直的屏幕空间在你查看一个文档时可以说是最宝贵的空间了。当你使用屏幕空间一次性查看多行文本时,使用递增式搜索一般比使用鼠标直接定位要快得多。
|
||||
|
||||
**养成使用ctrl-r(向前递增式搜索)和ctrl-s(向后递增式搜索)来在文档中进行移动的习惯**。__当你要向前或者向后移动5行左右,而且你又看得到移动的目的地时,你应该使用递增式搜索。__
|
||||
|
||||
要想高效地做到这一点,你并不需要搜索你光标目的地处的整个单词。让你的目光掠过目标点周围的一行或者一段话,选择一个看起来唯一性比较强而且比较好敲的单词,然后递增地搜过去。如果你选单词不是那么的唯一,那可能要按两三次crtl-r或者ctrl-s。但是放心,emacs会把已匹配的单词高亮显示,如果你看到匹配的东东太多了,按一下ctrl-g,然后重找一个词来递增导航。
|
||||
|
||||
一旦你掌握了它,**再怎么强调这一招数的强大都不会过份的**。你必须不断地重复直到你的手“自动地”去这样按才能算是真正掌握这一招。这时,emacs就好像变成你身体的延伸一样,成为你身体的一部分,你可以想都不用想就把这些微妙的按键敲出来。这类似于你学车时最终掌握的一些微妙的本能反应。
|
||||
|
||||
__条款5:使临时Buffer__
|
||||
|
||||
emacs最强大的功能之一就是她可以迅捷地生成一个**不与任何一个文件关联的buffer**。一旦你习惯了使用这一技术,你就对明显地感觉到其它编辑器这一功能性的不足。
|
||||
|
||||
要想建一个临时buffer,很简单,切换过去就是了!Ctrl-x b调用命令switch-to-buffer,然后你就瞎按一通adsflj。马上地你就来到一个草稿本上,你可以在上面做笔记,把临时结果导过来,或者用来做任何对你手头问题有帮助的事。
|
||||
|
||||
如果你打算维护多个临时buffer,你则应该给它们起些好记点的名字,比如:foo, bar, baz, buh...等等
|
||||
|
||||
如果你打算边靠边地比对两个buffer,你可把emacs屏幕水平地分割一下。(条款6会讲到)
|
||||
|
||||
由于你的临时buffer并不与任何一个文件关联,你杀它们就跟创建它们一样方便,用ctrl-k,也就是kill-buffer命令。
|
||||
|
||||
如果你打算保存临时buffer的内容了,也很简单,使用Ctrl-x Ctrl-w调用write-file命令。她会提示你输入一个文件名。保存文件后,你可以杀掉这个buffer(译注:区区真的很喜欢用杀这个词来替代关闭这一说法~),并可以随时通过打开文件重新访问它的内容。
|
||||
|
||||
__条款6:精通有关buffer(缓冲区)和window(视窗)的命令__
|
||||
|
||||
你会经常做一些需要打开多个视窗的编辑工作的。emacs使用一套与其它应用程序有些许不同的术语。一个buffer是指一个包含文本的逻辑空间,这个空间有可能会与一个进程或者文件关联;一个window是屏幕上显示着一个buffer(或者这个buffer的一部分内容)的可见区域。一个frame(窗框)则是一个你在操作系统说法里面管它叫window(窗体)的东西:一个独立的包含标题栏或者是类似东西的窗体。
|
||||
下面是几个需要重点掌握的命令:
|
||||
* ctrl-x 2: split-window-vertically -- 把你的当前window切成上下两个等高并且显示同一buffer的window(在你改变其中一个让它显示其它buffer之前)
|
||||
|
||||
* ctrl-x 3: split-window-horizontally -- 很多人并不常用这个,但有时它非常有用喔。--把当前window切成左右两个等宽window。
|
||||
|
||||
* **ctrl-x +: balance-windows ** -- 让所有可见的window近似等高。如果你刚用ctrl-x 2两次,那你就有两个1/4高的window和一个1/2高的,使用这招可以让这三个window变得等高。
|
||||
|
||||
* ctrl-x o: other-window --把光标移动到window列表的下一个window当中去,一般会把光标移到window下面一个window,或者回滚到最顶的window。
|
||||
|
||||
* ctrl-x 1: delete-other-window -- 让当前光标所在的window填满整个frame;其它的window都会消失。请注意buffer是由buffer-list的维护的,所以无论什么时候运行这个命令都是安全的啦。
|
||||
|
||||
**对话框:所有罪恶的根源**
|
||||
|
||||
有几个软件设计决择是促使emacs成为一个无比强大的编辑器的主要原因。其中一个就是:__emacs没有对话框__!当然,这也是emacs在一个只能显示文本的终端窗口也能提供完备功能的一个前提条件。但是巧就巧在,这正是使emacs暴走般强大的一个关键的特性。
|
||||
|
||||
对话框很废!对新手,经常会有焦点不明的问题,很多设计不好的程序还会因为对话框而自锁在刷新线程里面。对话框在你定制的视频模式下面从来就不会表现得很好。比如说吧,如果你设置了用双显卡设置了双头显示,在windows中的应用程序对话框老是会从错误的一个窗口中弹出来,这种事情跟生痔疮似的让人难受无比。
|
||||
|
||||
在一个单显示器的机器上,对话框有时会在出现在你意料之外的地方。哪怕是像Microsoft Office这样设计精良软件程序,模式对话框也会从一堆被隐盖的窗口中的某一个里弹出来,这会让整程序看上去完全没有回应,在你找到那个无赖对话框并把它置顶之前,程序就像死掉一样。
|
||||
|
||||
由于一些很奇怪的原因,对话框一般都大小不变的。这与应用程序窗体正好相反:它们几乎都是可改变大小的,也正因为如此,很多用户界面设计师要花好大的功夫来保证各种用户界面元素在窗体改变时能安排恰当的位置和尺寸。但是在默认情况下,大部分的对话框都是尺寸固定的--也许这是因为对话框根本就是窗口管理器设计完成之后再草草加入的补丁功能,而窗口管理器的设计压根儿就没把对话框考虑在内(猜猜俺是怎么知道这个的吧~~)。TMD,甚至在Java Swing中,对话框也是一团糟。
|
||||
|
||||
还有,你别跟俺提按钮的事儿,一提这个就来气儿。对话框在GUI世界里都有至少25年历史了,但是对话框上该有些什么按钮都还没有一个统一的标准--甚至连按钮应该放在哪儿都各有各的说法。有些对话框把按钮放在标题栏里、有些放在底下、有些左边、有些还在右边。当你想用标题栏中的控件来关闭对话框时,由于不同的GUI设计,很难100%保证它真的会按你想的那样去做。谁都知道这样很违背直觉,但是大伙儿又只能听之任之。
|
||||
|
||||
对话框的问题远不止于“输入焦点”、“尺寸变更”、“控件定位”。哪怕你把对话框做得和主程序的UI一模一样,对话框也无法具备主UI的功能。比如你定义(或者录制)了键盘输入的宏(不光是emacs有macro--其它程序如Excel或Word都有),那么这些宏在对话框中是无效的。如果对话框有一个可以卷动的控件,那可能你除了用卷动条之外再没其它办法可以卷页了(在emacs里的话,哪都能用C-v M-v)。
|
||||
|
||||
形象一点来说就是,现在你打开IE,选择Internet选项,进入‘高级’标签页。就在这儿了:你所有的全局自定义IE的选项都可怜巴巴地列在这儿。如果你想找到其中一个特定的选项,那就得小心翼翼地卷动,放大眼睛地看,再用鼠标点。休想用‘编辑/查找’,这当然得是一个模式的,尺寸固定的对话框。基本上,对话框都这样。
|
||||
|
||||
**救星:Buffer**
|
||||
|
||||
在Emacs中,所有的输入都写入buffer里,而__buffer是Emacs的‘一等公民’__。所有你最喜爱的导航快捷键,包括增量搜索,在任何buffer中都是可用的。你可以在任意buffer中选择和拷贝文本,在Emacs中没有什么‘模式的buffer’,所以你可以在保留任何buffer的内容的同时在其它window中工作,这些buffers不一定是可见的--这种‘对话框’的内容会一直保留在buffer列表中,直到你亲自删除它。
|
||||
|
||||
在其它的程序中你很难找到像Emacs的buffer系统这样的体验。一旦你领会到这种模型是多么的强大和一致,你使用其它程序时就会觉得有点不爽了--因为老会觉得它们的UI很碍事儿。
|
||||
|
||||
**精通buffer和window,并且对它们的操控游刃有余的时候,你就步上Emacs的大师之路了。**
|
||||
|
||||
__条款7:丢弃UI__
|
||||
|
||||
你不需要菜单栏,菜单栏只不过是给那些找不着北的新手用的拐杖而已。同样,你也不需要有大按钮的工具栏,不需要卷动条--这些东东都是给失败者的,而它们却占用了宝贵的屏幕空间。还是在.emacs中用下面的代码把它们全关了吧。
|
||||
|
||||
关掉这些东西,你不会丢失什么功能的,在下一个条款中我将谈到具体的高效作法。
|
||||
|
||||
(2006/01/02加入的注解)最近看到一个人回复,此君因为条款7而对本文全篇不爽。显然,他就是那种非常习惯于使用鼠标啊菜单啊之类东东的人,因此,觉得被称为“找不着北的新丁”很不爽。此君进一步阐述,说有无数的研究表明使用鼠标更加快捷。于是乎我也觉得自己应该把事情说清楚一点好:条款接下来的部分是全新的,这多亏了这位不忿的读者的Blog。
|
||||
|
||||
首先要说的是,我也常常希望emacs能有一个更猛一点儿的显示引擎(译注:这方面Xemacs做得可以),可以有像其它桌面应用程序一样的GUI和图像功能。然而未能如愿啊;我的博客文章"The Emacs Problem"(译注:自己google一下吧)对此有所阐述。当然,我也乐于看到emacs没加入这种功能。。诶,我说这些是想表明,我不是个没头没脑的反GUI份子。
|
||||
|
||||
**滚动条:是可有可无的**
|
||||
|
||||
由于用键盘就能达到同样效果,一般我都把emacs的滚动条关掉。然后,滚动条也有个好处:**它可以很形象地显示出你在文本中的编辑位置及文本的长度**;在状态区(译注:指mode line)的%-指示器不是那么好读取--无数研究都表明,确实如此。比如,这也是为什么美军在他们的反应堆中使用类似的比例量变尺。我们看数字时常出错,而读比例尺时不会~
|
||||
|
||||
所以,如果你觉得滚动条让你很爽,那我也没意见。就只是想提醒你,它会促使你去摸鼠标,而某些操作(比如跳转到文本头部)用键盘会更快,对此没必要做什么用户调查的。如果做一些计时试验的话,哪怕一些很耍赖的人,也不得不承认用键盘来导航更快捷。
|
||||
|
||||
假定我们打算在一个很长的文本缓冲区的头部和尾**部都插入包含80个连字符(-)的一行**,而你现在又在文本缓冲区中间编辑。这个例子有些做作,但我还真是做过一些需要包含全部文本内容的剪辑工作。用键盘的话,我三秒就可以完成,并且完全回到编辑状态。我要按的键盘序列是:"C-x t C-u 8 0 - RET C-x e C-u 8 0 -"
|
||||
|
||||
如果你用鼠标,没有什么简易的方法能让你在3秒内做到这些事情。你想啊,你得往返两次去摸鼠标,抓住滚动柄,他它拖到第一行,这时候光标还不一定在行首,他就是说,你还得小心地点到那个位置去。
|
||||
|
||||
当然,如果你勤加练习,可能5秒钟就得搞定,但何苦呢?如果经常要做这个,你应该写个宏啊。
|
||||
|
||||
**鼠标用例(only 1):区域选择**
|
||||
|
||||
有些操作明显用鼠标更快。**在emacs之外与你的窗口系统交互,如果另一个程序没有类似emacs的键盘导航功能,用鼠标一般会更快捷**。但是在emacs内部时,我能想到的鼠标比键盘方便的操作就是:区域选择,尤其是你打算选一个矩形文本时。
|
||||
|
||||
有时区域选择也是用键盘更好。比如,设定mark位置,然后用ctrl-n来选行,用ctrl-f一次多选一个字符。键盘的按键重复率是和硬件设定相关的,有时会觉得很慢。我自己的显示设定在一屏中可以包含大约100行。如果从中间移到屏幕底部,大约要用5秒。如果用鼠标来回操作,需要4秒。所以在可见区域选择时,用鼠标也不是很超值。
|
||||
|
||||
但是,如果我是想选比一屏还要多的文本,或者选区的开头和结尾都在行内位置时,用鼠标就又可靠双快捷了。我也乐于使用。
|
||||
|
||||
使用鼠标跟关掉UI不是一个事儿,只不过是相关的事情,所以就搁一块说罢了;我20年前就做过这样的计时试验了。我衷心地建议你把菜单关掉~
|
||||
|
||||
**菜单:丢了它!**
|
||||
|
||||
用菜单来探索,了解更多的emacs功能是不错的。不幸的是,它比较容易产生误导,让你认为emacs的功能就那么多了。其实,很多emacs扩展并没有什么菜单支持――只有非常细心的扩展模块设计者才会花时间去添加菜单支持。所以如果你想只用菜单来了解emacs,你会错过很多很多功能的。
|
||||
|
||||
菜单的另一个问题,有点儿类似于之前我们提到的对话框:它没有很强的伸缩性能。如果你用菜单来给用户提供1500个选项,这个菜单的显示搞不好会把窗口整死的;便如果用Emacs的buffer来做,小case啦,还有很诸如漂亮布局和分组显示等额外的好处。你用M-x list-colors-display或者M-x list-faces-display就知道我说的东东了。。
|
||||
|
||||
菜单还有一个(大)问题,它没有自动补全~当你查看到一个比较深的子菜单层级中,以不小心进错一个子树时,很容易觉得自己是迷路了。没有什么探索方法比较可搜索的帮助系统更加灵活了,在MS的程序中是这样,在emacs中也是。
|
||||
|
||||
最后,一旦你记住一个菜单功能了,每次你要使用时,你都得重新点击(搞不好还得进入子菜单)来调用。你调用次数越多,浪费的时间也就越多(相对于使用键盘来说)。
|
||||
|
||||
所以我觉得emacs菜单不好:不能展现emacs全部的功能;不能给出提示帮助你找到你想要的功能;选择一多时菜单又撑不住(所以相比于树视图之类的组件,它不算是一个很通用的UI机制。);当你知道怎么用时,用起来又很慢。
|
||||
|
||||
简单来说呢就是:关掉菜单!就像那些闪亮的按钮一样~诶~~任何重要到要提供一个快捷按钮的操作,都应当有个快捷键。
|
||||
|
||||
__条款8:掌握最重要的帮助功能__
|
||||
|
||||
要找出当前buffer中所以的按键功能,输入M-x describe-bindings。它显示一个包含按键及被绑定命令的列表。
|
||||
你把光标移动到相应的命令上,按回车,emacs会显示那个命令的帮助。
|
||||
|
||||
想知道一个按键操作是干什么的,使用M-x describe-key,然后按入你感兴趣的按键序列。如果你输的序列是有绑定的,emacs会直接转到那个按键的帮助信息中。
|
||||
|
||||
如果你对某个功能感兴趣,想找出相应的命令,并且你已经心里有个大约的命令名,那么你可以用M-x apropos,然后再输入一个正则表达式(参见条款9)来搜索命令名。所以的emacs命令(也包括函数和属性表)都存在一个全局表中,以备M-x apropos检索。
|
||||
|
||||
比如:你**想找一个功能**,可以把一个buffer放到buffer列表的最末端,你就可以用M-x apropos-command,再输入“buffer”,就显示出所有200来个包含有buffer这词的命令。在这个列表里面靠前的有一个命令,bury-buffer,它的文档写道:
|
||||
bury-buffer M-x bury-buffer RET Command: Put BUFFER at the end of the list of all buffers.(译注:帮助真的是英文,要养成看E文的习惯啊)
|
||||
|
||||
瞧!这不就是你要找的吗?用好(regexp)正则表达式的话,你很容易就可以限定搜索显示的范围。
|
||||
|
||||
要说最最重要的emacs帮助命令,当属M-x info,这命令会开启emacs内置的交互式,菜单驱动的Info引擎。你应该学学怎么用Info。它包含数千页的文档,而且是超文本链接的(很不巧,是web出现之前的emacs自有链接风格),所以比man页要易读得多。一旦你掌握了Info系统的导航键,用起来铁定比用浏览器看HTML帮助要快,即便是看本地文件也是如此。一方面,是因为emacs info有跨info文件搜索的功能,另一方面,就只归功于emacs有相比于浏览器更好的文本导航能力。
|
||||
|
||||
__条款9:掌握Emacs的正则表达式__
|
||||
|
||||
最好的办法,就是买本Friedl的书《Mastering Regular Expressions》。绝对值!任何一位程序员都该有一本,管你用什么语言什么编辑器。
|
||||
|
||||
emacs的正则表达式有些大伙儿都不太喜欢的特质,但这并不是不可克服的,一旦你学到手,你的编辑功力会精进的喔~
|
||||
|
||||
与正则表达式相关的命令中,最重要的是 isearch-forward-regexp和 isearch-backward-regexp。默认设定下,分别绑定于 ESC C-s和 ESC C-r,但这么按有点儿僵。**任何要用到Escape键的操作都很僵**,而且如果是在我的Compaq电脑上,Alt-Ctrl-s这个按法emacs无法截获,因为它是弹出系统诊断对话框的热键。
|
||||
|
||||
由于使用频繁,我把自己的isearch-*-regexp命令绑定到 Alt-r 和 Alt-s上了。alt-s一般没有默认绑定,alt-r默认为我不怎么使用的move-to-window-line,因为我用条款4的方法在编辑窗口移动。
|
||||
|
||||
有些mode坚决要重绑定alt-r和alt0s,这很烦人――害我要使用per-mode的招数来重绑定。但我没办法把所以的mode都招呼到。如果有哪个哥们儿知道怎么防止这两个键被任何mode重绑定,麻烦你教我一下,我会非常感激的。
|
||||
|
||||
另外两个也很重要的正则表达式命令是 replace-regexp 和 query-replace-regexp。它俩功能差不多,提示你输入一个正则表达式和替换字符串,只是 query-replace-regexp 要求你在每一个可能的替换发生时输入y或者n。
|
||||
我跟 query-replace-regexp 关系很铁,以至于还得给它起个外号(别名~):
|
||||
(defalias 'qrr 'query-replace-regexp)
|
||||
这样一来,我就用 M-x qrr 就可以使用这个功能了。
|
||||
|
||||
|
||||
其它有用的命令还有 M-x list-matching-lines -- 可以把buffer中匹配某一regexp的行全列出来; M-x apropos -- 就是那个把所以匹配的命令都列出来的帮助命令
|
||||
|
||||
emacs正则表达式最常被问到的是:“怎么在正则表达式或者替换字符串读取时输入回车呢?” 如果仅仅简单地直接打回车,那emacs会认为你把regexp输完了。(这也是推荐qrr而不是 replace-regexp的原因啊――――在你非常有信心一次试写就可以把正则表达式写对之前,至少,我还没到那个境界)。
|
||||
回答是:要输入一个 ^j (译注:也就是Ctrl-j) 字符。在你要输入表达式或者替换串的时候,如果你要输回车符,选按Ctrl-q然后再按Ctrl-j。Ctrl-q是emacs的"quote"命令,它不执行下一个按键,而是把它插入到当前buffer或者minibuffer当中。
|
||||
|
||||
|
||||
还有一些其它与regexp相关的知识:
|
||||
* __在elisp代码中,你写两次转义("\\"),而在minibuffer输入时,你只写一次转义就OK了。__
|
||||
* 由于emacs代码有很多要匹配括号,所以emacs反转了括号的语义,在emacs的regexp中,"(",")"匹配实际的括号,而"\)","\("则用以建立匹配组(字串)。
|
||||
* 在替换串中,使用\1 \2 ...来插入匹配组中的字符串
|
||||
* 如果你输入的regexp没有正确工作,把结果undo掉,重新输一次命令,当提示输入表达式时,使用上下箭头按键可以找出你之前输入过的记录。这样可以习省时间开销和防止混乱。
|
||||
|
||||
__条款10:掌握一套细致的文本处理命令__
|
||||
|
||||
emacs提供很多小巧实用的命令来对文本进行外科手术作业,极大地提升了编辑效率。
|
||||
|
||||
如果是初学者,不要经不住诱惑把ctrl-k重绑定到一个删除整行的命令上。我知道,这是很多其它编辑器的"删行"命令。但相比于kill-line的默认行为,这显行很粗造。默认行为,删除到行末而不把行末换行符删除,会让你有更细致的操控,当你在对全盘文本进行外科手术作业时这会提高效率的。相信我:所有的emacs用户都用过那些只支持鲁莽"kill-whole-line"的编辑器,他们早就用过了,但还把kill-line的默认行为设成现今这个样子,不是没有原因的。
|
||||
|
||||
**键盘宏记录**
|
||||
|
||||
我可以毫不夸张地说,emacs的宏是全宇宙最酷的东东了。从感觉上讲,它们是一种特定用途的细致操作,因为你当即把它们做出来,然后就当即用来解决手头特定的问题。**只要你觉得自己要进行一组特定的,有迹可寻的操作,而且不止一次(比如10次,15次)时,写一个键盘宏,这真的非常简单高效。**
|
||||
|
||||
先试运行一下宏是有益的。首先把光标移到你第一个要改动的地方,按下Ctrl-x ( 启动宏记录。继续你的编辑操作,确保你的光标刚好在下一行(或者说下几行,视情况而定),这样就可以按模式运行了。用Ctrl-x )来结束宏录制。再来就是用Ctrl-x e(call-last-kbd-macro)来调用宏了。。
|
||||
|
||||
|
||||
有时,定义一个可靠的宏算得上是一种技艺――你得学会在添加操作之前,使用 beginning-of-line和 end-of-line 这样的**锚点来保证宏操作在一个可确定的位置上。**
|
||||
递增搜索可以很方便地跳过下一个位置。如果你在记录宏时使用了isearch,那么宏调用时,isearch也会被执行,非常方便。
|
||||
在记录宏时有时会有些小的失误,这不要紧,直接改正这个失误,继续录宏。在宏调用时,这个失误会反复出现,然后反复被改正,而且很快,你几首注意不到。
|
||||
|
||||
用宏的技巧是很死的:确保你的宏完成它的任务,并且不要放弃,哪怕有时录一个正确的宏比你手工编辑还慢。因为下一次你就会快很多,久而久之,会成为你的本能反应。键盘宏是emacs最强大的功能之一,它让你的生活更美好~~~
|
||||
最捂一个有关宏的招数:有时候你得调用它们几百次,而且不止在一个文件中,可能在多个文件中。这时你应该把 call-last-kbd-macro 绑定到一个单次按键中,比如f5啦。这时你可以翘起二郎腿,反复地按那个键,再看看编辑器上文本的变化有没什么意外即可。所以把综绑定到一个很远的按键也是可行的:
|
||||
|
||||
(global-set-key [f5] 'call-last-kbd-macro)
|
||||
|
||||
|
||||
**调换XXX的功能**
|
||||
虽然看起来很古怪,但一旦你习惯了它们,你就会发现调换功能出奇地有用。可能最突出要是__默认绑定到alt-t的transpose-words了:它的作用有两个,一个是调换连续的两个词,一个是把单词在句子中拖来拖去。__
|
||||
transpose-words对mdoe特定的语法和词法边界是有感知的,比如。把光标放到下面两个词的中间:
|
||||
([this])-is
|
||||
然后按alt-t,结果变为:
|
||||
([is])-this
|
||||
|
||||
你可以在连字符,html标签,和其它标点符号之间调换单词。这是一个急你所需的灵活功能。
|
||||
|
||||
当你调换两个词时,比如"dog food",左过的词与右边的词互换了(这里假定你把光标放到两个词中间),变成"food dog"。但是这时的光标是还是在被移到右边来的这个词(food)的右边。所**以如查你不停地按调换键,那个词就不断地在句子中向右边爬行驶**。我不知道有什么内置的方法可以让一个词往左边爬的,但是如果要写一个的话,也一点也不难。。相应的eclipse插件,可能就得要5000行代码,分布在60个文件中,得花个9天时间来编写和调试了。。。
|
||||
|
||||
你还可以调换字符,行,句子,段落。无论你在编写纯文本还是程序时,这些都是很有用的,试验并试着记住它们,目标是形成本能反应~
|
||||
|
||||
下次要写的东东…
|
||||
|
||||
一开始我有点想写50个条款的,就像Scott Meyers的力作《Effective C++》那样写50个条款。但最终我还是放弃了用一次休息时间就写出50个tips的相法,并把题目中的50改成了10。我至少花了两个小时坐下来写了这篇文章。要是一个eclipse用户的话,很可能会愿意花更多时间在文档中找寻可以帮助写blog的重构工具。
|
||||
|
||||
下面列一下接下来想到的,有用的条款吧:
|
||||
1。 fill-paragraph (alt-p) -- 智能地帮你把文本分行,这是必备良药啊,在注释里面都能用。
|
||||
2。 gnuserv: 自动用emacs来开启特定文档(包括你浏览器的"view source")。
|
||||
3。 M-x dired: 一个很强的文件/目录管理工具,它提供了一些其它工具完全没有的强大功能(至少据我所知),比如用regexp把某个用户组的文件重命名。
|
||||
4。 whitespace处理命令:C-x C-o(delete-blank-lines), delete-trailing-whitespace, tabify 和 untabify 等等。。。。
|
||||
5。__ nxml-mode__: 唯一让你在处理xml时编辑如飞的方法,作者是xml高手James Clark;完全把其它基于IDE的XML编辑器比下去了。。
|
||||
6。 __picture-mode__: 搞ascii艺术时最好用的东东。
|
||||
7。 minibuffer管理: 掌握递归编辑,在各种情况下怎样中断退出,命令补全及其它各种输入技巧。
|
||||
8。 不费吹费之力的导航: 绑定一些各个方向移动光标的命令:以字符为单位,以词为单词的。使用alt加某个字符的快捷键组合。
|
||||
9。 区域管理: 选一个不太难看的区域高亮颜色。
|
||||
10。 矩形区域命令: 这是另一组很神奇的命令(译注:不过很多编辑器现在也都有这功能了)。
|
||||
11。 emacs shell: 高效使用emacs shell的技巧。
|
||||
12。 __align-regexp__: 我新收藏的命令,最近才学到的,几乎天天都用到。
|
||||
13。 frame初始化: 如何在每次打开emacs时,自动根据显示器尺寸把emacs窗口设定好。
|
||||
14。 使用goal column: 每个emacs强人都该知道的。
|
||||
15。 设定fill column: 最大发挥 fill-paragraph 和 fill-region的功能。
|
||||
16。 优化操作系统设定: 设定键盘重复率,设定好的emacs字体,等等。
|
||||
17。 浏览编辑归档文件: tar,gzip,zip,jar等等。这没什么奇怪的。
|
||||
18。 高级绑定: 学习绑定的语法,home/end等其它不常绑定的按键,学习如何特定于buffer来绑定按键。
|
||||
19。 掌握 kill ring, 包括用 Derek upham的新mode来查看它的内容。
|
||||
20。 掌握 Info: 定制你的Info目录,查找和添加新的Info文档,高级导航及书签功能。
|
||||
21。 使用好__ M-x customize__: 学习它的运作,以及怎么避免使用它。
|
||||
22。 工具程序: M-x calendar, M-x calc, 及其它。
|
||||
|
||||
这个列表会一直增长下去……呵呵,在某天我会再把它们写出来吧。
|
||||
就这么多了,我得睡觉啦~~~。
|
||||
|
||||
后面是对这个blog的回复,也有一些不错的建议喔~
|
||||
++
|
||||
|
||||
Comments -----------------------------------------------------------------------------------------------------
|
||||
|
||||
Some random comments:
|
||||
|
||||
To yank at the i-search prompt, use M-y instead of C-y. The emacs info node on Incremental Search talks about the rebinding of C-y, C-w, etc at the i-search prompt.
|
||||
|
||||
To repeat execution of the last kbd macro, after hitting C-xe to run it once, keep hitting just the 'e' key for repeated execution.
|
||||
|
||||
Zap-to-char (M-z) is incredibly useful if you need to change myDatafileHandler to myStreamHandler and point is at D (the first char to change). Simple M-z e to zap the "Datafile" part and type in the replacement. This is not orthogonal to the backward-kill-word (bound to C-backspace for me since that works in windows browser windows as well as everything else) so there's a feel needed for which is optimal when, which for me mostly depends on where point is already.
|
||||
|
||||
Posted by: Ami F. at January 23, 2005 07:12 PM
|
||||
|
||||
"Swap Caps-Lock and Control": Or you could just get yourself a keyboard that's already swapped, or that lets you swap them in hardware. The Happy Hacking Keyboard is an example of the former. I like the Avant Stellar keyboard for the latter.
|
||||
|
||||
"Binding Alt-r and Alt-s": Try setting up a minor mode with the definitions you want. Then stick that keymap on the *front* of MINOR-MODE-MAP-ALIST.
|
||||
|
||||
Other tips:
|
||||
|
||||
Use `iswitchb' mode. It's faster for switching between buffers, and it provides more feedback.
|
||||
|
||||
Use P4 mode. But be sure to download a more recent version than what we have installed.
|
||||
|
||||
Emacs' integration with X11 selections is written to work well with xterm's sucky default policies. That means it works badly with modern apps and badly over slow network connections (say, a VPN from home). I have written a new set of commands to make Emacs talk to the clipboard, and they make life much easier.
|
||||
|
||||
Posted by: Derek U. at January 24, 2005 07:37 PM
|
||||
|
||||
Doing the swapping of control/cap-lock key can be done in \\HKEY_CURRENT_USER\Keyboard Layout instead of under \\HKEY_LOCAL_MACHINE.
|
||||
|
||||
Posted by: Chris W. at January 27, 2005 07:52 AM
|
||||
|
||||
I disagree with your agressive rebinding of keys. I used to rebind almost all my emacs keys so they would be more familiar to a windows user (Ctrl+C does copy, Ctrl+V is paste, etc). However, I found myself at a loss when I tried using my neighbor's computer with the default emacs installed.
|
||||
|
||||
Always learn default emacs keybindings first, then over-write them as you find appropriate. For example, I rebound Ctrl+J to be the goto-line macro. By default, Ctrl+J enters a newline. F7 is not bound to anything by default, so I made that bound to the compile macro (that keybinding actually comes from Visual Studio). That is about the extent of the keybindings I need/use. And, if I have to use a non-customized emacs, I can still get work done.
|
||||
|
||||
Cheers,
|
||||
-Brian
|
||||
|
||||
Posted by: Brian M. at January 27, 2005 10:29 PM
|
||||
|
||||
To not pursue aggressive editor and keyboard customizations because other people stick to the standard is a bogus argument, in my opinion. Firstly, how often do you really use a terminal other than your own? And even then, how often do you write just scads of code there? When I do this, it's usually for just a couple of quick edits. So, why optimize for that 1% of time when you're not at your own setup? Secondly, if it does annoy me enough to care, I can always just load my rc file remotely. I use vim and have my .vimrc hardlinked into my /workplace directory so I can just say vim -u /net/ericw/workplace/.vimrc if I really need my magic. I'm certain the same can be done in emacs.
|
||||
|
||||
Customization is one of the main selling points of powerful editors, and our wrists are two of our most valuable assets as developers, so I don't understand why people eschew customization just because they fear that small percentage of the time when they won't have it.
|
||||
|
||||
Posted by: Eric W. at January 28, 2005 07:34 PM
|
||||
|
||||
Brian, I'm afraid I'm with Eric on this one.
|
||||
|
||||
I have friends who have nonstandard keyboards, in some cases to avoid repetitive-stress injury. I can't type at their workstations. I have this little secret, though, that works like a charm. I say: "uh, you type."
|
||||
|
||||
OK, not much of a secret, but it's gotten me by.
|
||||
|
||||
Everyone customizes their environment. Some SDEs use fonts so small I actually can't read them. Some use custom window managers with non-CUA hotkeys and behavior. People use Windows, Linux, MacOS. There are different Unix shells with different default keybindings and aliases. Should we tell everyone they have to use plain-vanilla Windows installations with no customizations?
|
||||
|
||||
You're effectively arguing that we should all reduce ourselves to the least common denominator of productivity. This argument has been debunked in other domains (e.g. should we make people with good vision wear blur-inducing glasses, so nobody feels like they're at a natural disadvantage?), and it doesn't hold water in ours either.
|
||||
|
||||
You're welcome to use the default bindings yourself, of course. But I wouldn't get on a bandwagon that tries to discourage people from getting better at their jobs. It's a slippery slope that I think you want to avoid.
|
||||
|
||||
Anyway, we now issue laptops with wireless iVPNs, so you can even bring your environment with you. It's just not an issue anymore.
|
||||
|
||||
Posted by: Steve Yegge at January 28, 2005 09:30 PM
|
||||
|
||||
I just want to know the tips you allude to in number (8) of your "Tune in next time..." section. How do you do the up/down/left/right browsing? I've been trying to train myself to use C-n, C-p, C-f, C-b and friends, but its awkward, and it isn't getting easier. Also, can I plllleeeeasssseee see your .emacs file :)
|
||||
|
||||
Posted by: Charles G. at February 18, 2005 01:47 AM
|
||||
|
||||
On March 4 2006, Luke Gorrie wrote:
|
||||
|
||||
Howdy,
|
||||
|
||||
I know it's bad form to comment on a blog entry without having read it thoroughly but I will take a chance because your eternal salavation is at stake.
|
||||
|
||||
I use C-h for backspace in Emacs and move `help-command' elsewhere:
|
||||
|
||||
(global-set-key "\C-h" 'backward-delete-char-untabify)
|
||||
(define-key isearch-mode-map "\C-h" 'isearch-delete-char)
|
||||
(global-set-key [(hyper h)] 'help-command)
|
||||
|
||||
and this also works in the shell along with C-m, C-j, C-i, etc.
|
||||
|
||||
Offered for your consideration. :-)
|
||||
|
||||
On March 5 2006, Anupam Kapoor wrote:
|
||||
|
||||
hi,
|
||||
regarding tip #7, imho, its better to just disable it via Xresources,
|
||||
rather than loading it all up and making it invisible (as you have
|
||||
shown) via:
|
||||
|
||||
,----
|
||||
| ! better to turn this off here than in .emacs
|
||||
| ! where it has already been loaded.
|
||||
| emacs.menuBar: off
|
||||
| emacs.toolBar: off
|
||||
|
|
||||
| ! no scrollbars fur me
|
||||
| emacs.verticalScrollBars: off
|
||||
`----
|
||||
|
||||
kind regards
|
||||
anupam
|
||||
|
||||
On March 9 2006, Scott Anderson wrote:
|
||||
|
||||
Steve,
|
||||
|
||||
Great article.
|
||||
|
||||
Reading section 7, I became amused by the person who claimed that
|
||||
"countless studies" (or whatever) had proven that the mouse was
|
||||
faster.
|
||||
|
||||
I'm guessing he never studied GOMS, which is a method of decomposing
|
||||
UIs into their basic operations and then performing objective
|
||||
complexity and time analysis.
|
||||
|
||||
A quick typist can hit about 10 keys per second, or .1s per key. To
|
||||
use a mouse there are four movements involved: move from the keyboard
|
||||
to the mouse, move the cursor to a location, perform some operation at
|
||||
the location, then move the hand back to the keyboard.
|
||||
|
||||
Moving the hand takes about .4s. Moving the mouse cursor on the screen
|
||||
takes .5s. So without even doing anything, you've used 1.3 seconds. A
|
||||
mouse click takes .1 seconds, and if you're dragging something, you
|
||||
measure the click down, the drag, and the release, adding up to
|
||||
another .7 seconds.
|
||||
|
||||
So let's say I want to highlight a line for copy:
|
||||
|
||||
mouse:
|
||||
.4 move to mouse
|
||||
.5 move cursor to first character
|
||||
.1 depress button
|
||||
.5 drag to highlight (and this is optimistic, depending on how good
|
||||
you are with finicky targets like highlighting)
|
||||
.1 release button
|
||||
.4 move to keyboard
|
||||
.2 copy (alt-w, ctrl-c, whatever. count control keys as a separate keypress)
|
||||
|
||||
2.2 seconds to perform.
|
||||
|
||||
kb scenario 1: best case: already at beginning of line
|
||||
.2 mark (ctrl-space)
|
||||
.2 end-of-line (ctrl-e)
|
||||
.2 copy
|
||||
|
||||
.6 seconds to perform, or nearly 4 times as fast.
|
||||
|
||||
kb scenario 2: worst case: requires navigation: 30 lines down, line
|
||||
starts with "Reading"
|
||||
.9s move to start of line (ctrl-r readi ctrl-r)
|
||||
.2 mark (ctrl-space)
|
||||
.2 end-of-line (ctrl-e)
|
||||
.2 copy
|
||||
|
||||
1.5s, still faster
|
||||
|
||||
|
||||
As it turns out, the only thing a mouse is really good for is
|
||||
something involving a gross motor movement, like moving a window or
|
||||
the like. Unless you're a crappy typist.
|
||||
|
||||
Anyway, good article, and I'm looking forward to reading the rest of
|
||||
them.
|
||||
|
||||
Regards,
|
||||
-scott
|
||||
|
||||
Back to Stevey's Drunken Blog Rants image of my email address, steve dot yegge at ye olde gmail
|
||||
245
Zim/Utils/emacs/el-get.txt
Normal file
@@ -0,0 +1,245 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T13:45:24+08:00
|
||||
|
||||
====== el-get ======
|
||||
Created Saturday 07 January 2012
|
||||
https://github.com/dimitri/el-get
|
||||
|
||||
Short Story: el-get allows you to install and manage elisp code for Emacs. It supports lots of** differents types of sources** and is able to **install them, update them and remove them**, but more importantly it will __init __them for you.
|
||||
|
||||
That means it will __require__ the **features** you need,__ load__ the necessary files, set the__ Info__ paths so that C-h i shows the new documentation you now depend on, and finally __call__ your own** :post-init** function for you to setup the extension. Or call it a package.
|
||||
|
||||
===== Status and Version Numbers =====
|
||||
Current el-get status is stable, ready for daily use and packed with extra features that make life easier. There are some more things we could do, as always, but they will be about smoothing things further.
|
||||
|
||||
==== • Latest released version ====
|
||||
el-get version 3.1 is available, with a boatload of features, including **autoloads **support, **byte-compiling** in an external "clean room" Emacs instance,__ custom__ support,__ lazy initialisation__ support (defering all init functions to //eval-after-load//), and multi repositories ELPA support.
|
||||
|
||||
==== • Version numbering ====
|
||||
Version String are now inspired by how Emacs itself numbers its versions. First is the **major **version number, then a dot, then the **minor** version number. The minor version number is 0 when still developping the next major version. So 3.0 is a developer release while 3.1 will be the next stable release.
|
||||
Please note that this versioning policy has been picked while backing 1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
|
||||
|
||||
===== How to Install it? =====
|
||||
|
||||
Here’s the **lazy installer(先安装el-get文件,然后将相关代码添加到启动文件中,当emacs下次启动时会自动下载安装相应的软件包)**:
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working el-get.
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp)))
|
||||
|
||||
You have to type__ C-j __with the cursor at the end of the last line, but** still on** the line. C-j runs the command// eval-print-last-sexp//, so it will evaluate the code you’re looking at, and that will git clone el-get at the right place.
|
||||
|
||||
上面的代码只是**下载**el-get安装文件到本地目录,并没有启动和配置它。所以需要把下面的**启动代码**添加到emacs的启动文件中。
|
||||
Note that you can add this elisp code into your **emacs init file** directly, as the installer code will detect if el-get is already installed. Notice that doing so directly will require internet access to start emacs. You can avoid this with the following snippet instead:
|
||||
把下面的代码添加到emacs的启动文件中.emacs
|
||||
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get") ;;注意,加载的目录路径。
|
||||
|
||||
;;;如果已经下载到本地了则不需要重新下载。
|
||||
(unless (require 'el-get nil t)
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
|
||||
See next section for details about how to setup you emacs so that it’s able to benefit from el-get automatically.
|
||||
|
||||
===== How to install the developer version (master branch)? =====
|
||||
The lazy installer uses the default el-get-install.el file which targets the **2.stable branch**. To install el-get directly on the **master branch**, summon the el-get-master-branch variable into existence:
|
||||
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working developper edition of el-get.
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(let (el-get-master-branch)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
|
||||
|
||||
===== Basic usage =====
|
||||
Now that el-get is installed, simply use__ M-x el-get-install__ and pick whatever package you need. Arrange to have el-get part of your setup, so that at** next emacs startup the installed packages are initialized**. Here’s how to:
|
||||
可以直接使用el-get-install安装自带的sources中的扩展,也可以在.emacs等配置文件中添加**扩展列表**,这样emacs下次启动时就会安装和初始化这些扩展。
|
||||
注意:__只有__添加在配置文件中的扩展,el-get才会在启动时自动加载并初始化它们。因此通过el-get-install方式安装的扩展,需要在下面的配置文件中el-get-sources中添加相应的package name。
|
||||
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless (require 'el-get nil t)
|
||||
(with-current-buffer
|
||||
(url-retrieve-synchronously
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el")
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp)))
|
||||
|
||||
**(el-get 'sync)**
|
||||
|
||||
That’s the basic setup.
|
||||
|
||||
===== Advanced setup with local recipes =====
|
||||
Of course, my emacs setup is managed in a private git repository. Some people on //#emacs// are using //git submodules //(or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy canonical list of packages I depend on to run emacs, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
(require 'el-get)
|
||||
|
||||
;; local sources ;;非el-get自带的sources,如果name和自带的相同,则这里的设置会**覆盖**自带里的设置。
|
||||
(setq __el-get-sources__
|
||||
'((:name magit
|
||||
:after (lambda () (global-set-key (kbd "C-x C-z") 'magit-status)))
|
||||
|
||||
(:name asciidoc
|
||||
:type elpa
|
||||
:after (lambda ()
|
||||
(autoload 'doc-mode "doc-mode" nil t)
|
||||
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
|
||||
(add-hook 'doc-mode-hook '(lambda ()
|
||||
(turn-on-auto-fill)
|
||||
(require 'asciidoc)))))
|
||||
|
||||
(:name lisppaste :type elpa)
|
||||
(:name emacs-goodies-el :type apt-get)))
|
||||
|
||||
(setq my-packages
|
||||
(append
|
||||
'(cssh el-get switch-window vkill google-maps nxhtml xcscope yasnippet) ;;这个列表里的扩展来自**自带**的sources
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
(el-get 'sync my-packages) #注意, el-get的配置一般以该命令结束。
|
||||
|
||||
So now you have a pretty good documentation of the packages you want installed, **where** to get them, and **how** to install them. For the advanced methods (such as **elpa** or **apt-get**), you basically just need the **package name.(因为el-get会自动调用系统的包管理系统来安装它们)。** When relying on a bare git repository, you need to give some more information, such as the** URL** to clone and the** build** steps if any. Then also what **features **to require and maybe where to find the **texinfo** documentation of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of all that **in a central place**, but this very description is all (el-get) needs to do its magic. This command will __check__ that each and every package is installed on your system (in __el-get-dir__) and if that’s not the case, it will **actually install it**. Then, it will__ init__ the packages: that means caring about the __load-path__, the__ Info__-directory-list (and dir texinfo menu building) the__ loading__ of the emacs-lisp files, and finally it will __require__ the features.
|
||||
emacs每次启动时,el-get都会检查el-get命令的参数列表中的各扩展是否安装到系统的el-get-dir变量指定的目录中,如果没有则自动下载并安装它们。然后初始化相关的软件包如:添加load-path变量,load相关文件,require相关文件等(这些初始化配置信息可以在:after、:featers、:info、:load-path等属性中指定)。
|
||||
|
||||
===== How to use it? =====
|
||||
You see that el-get-sources example up there? It **finishes with a single (el-get) call**. That’s it. It will__ install__ new sources **on the list** and only__ init __already installed ones.
|
||||
如果已经安装(如直接通过el-get-install命令)的package但没有添加到该list中,则el-get不会初始化它们。
|
||||
|
||||
The status of each package is tracked into __~/.emacs.d/el-get/.status.el__ (by default,__由el-get-dir变量指定安装包的位置,默认为~/.emacs.d/el-get__) and can get the values required, installed or removed.
|
||||
|
||||
===== Sync or async? =====
|
||||
Most often you want **el-get-install** and **el-get-build **to stay out of the way and be //asynchronous//, so that you can continue using Emacs while your new package is getting ready. But imagine you’re starting up Emacs after a **git pull** on the other computer (after a commute, say), and there’s some newer packages for this instance to consider installing.
|
||||
|
||||
Now you want a synchronous install, right?
|
||||
|
||||
So, by default (el-get) is __asynchronous__, but you can ask for it to be sync, or to still be asynchronous but to wait until it finished before to give control back:
|
||||
|
||||
(el-get 'sync) #异步更新
|
||||
(el-get 'wait) #接着添加这条命令后,变为同步更新。
|
||||
|
||||
You even get a progress report!
|
||||
|
||||
===== Sources =====
|
||||
See the documentation of the __el-get-sources__ variable for details. Please note that el-get-sources is another source location for recipes, adding to your **el-get-recipe-path**.
|
||||
注意,可以el-get-recipe-path变量来指定__sources目录,这样el-get会自动到相关目录搜索要安装的package的配置文件__。
|
||||
|
||||
Note that you can also give a mix of **packages symbols**,** inline recipes **and **source lists** to __el-get__ as arguments, and completely** bypass **the el-get-sources variable.
|
||||
|
||||
(el-get 'sync) ;**;不指定参数时,默认使用el-get-sources类表中的packages**
|
||||
(el-get 'sync 'package 'name 'list-of-packages-names-or-symbol)
|
||||
|
||||
It is still __recommended__ to (setq el-get-sources '(list of packages)) then use (el-get 'sync), so that commands such as **el-get-update** know which packages to update.
|
||||
但是最好还是使用el-get-sources参数来指定安装的package(不管是来之本地的sources还是自带的sources),这样其它的__默认使用该变量__的命令才可以正常工作。
|
||||
|
||||
===== Recipes =====
|
||||
Some sources are contributed to el-get **directly**, so that you only have to put in the el-get-sources the__ name of the package__ you want to install.
|
||||
Should you need some **local specific setup(本地化配置,但还是使用自带的文件下载安装扩展)**, you can do that by providing __a partial sources__ missing the** :type **property: your local properties will get __merged into__ the recipes one.(在el-get初始化代码中指定。)
|
||||
|
||||
Also, the variable __el-get-recipe-path__ allows you to maintain** local recipes **in case you either dislike the default one or are crafting some new one not commited to the main repository yet. But please do consider sending them over!
|
||||
如果想在一个单独的文件里本地化配置自带的软件包,要注意文件中不要有:type属性,同时该文件要在自带的文件__前__加载。因此,该文件所在的目录要在el-get的recipes__前被搜索到__。
|
||||
|
||||
We do not intend to provide recipes for advanced types such as apt-get and elpa because there’s so little to win here, and maintaining a package list would take too much time.
|
||||
|
||||
===== Package setup =====
|
||||
The package setup can either go into the __:after function__, or in a file named __init-package.el__ in __el-get-user-package-directory__. Any such named file will get automatically loaded by el-get at init time, if it exists.
|
||||
|
||||
===== Build Commands =====
|
||||
__Avoid using make install__, which will usually move files into a "system location." In our case, you probably just want your package //foo// to be all installed into //~/.emacs.d/el-get/foo(实际安装位置的顶级目录由//__el-get-dir变量指定__//)//, right? So, no make install.
|
||||
|
||||
===== Byte Compiling =====
|
||||
el-get will byte compile the elisp for the package when its **source definition** includes a__ :compile__ property set to the** list** of files to byte compile (or to a single file), or __all__ the .el files found in the package when there’s** no :build** command.
|
||||
|
||||
===== Hooks =====
|
||||
el-get offers a variety of specific hooks (read the source), and two general purposes hooks facilities: **el-get-post-install-hooks **and **el-get-post-update-hooks**, called with the package name as argument.
|
||||
|
||||
===== Some more commands? =====
|
||||
Yes, ok.
|
||||
|
||||
* M-x el-get-list-packages
|
||||
Opens a buffer listing **all known packages** (those for which you have a recipe). The listing includes the package name, its status (one of "available", "installed", "removed" or "required") and the package description. The description is a free form text and has not been provided for all recipes. Please also note that el-get-emacswiki-refresh will create recipes omitting the description as of now.
|
||||
|
||||
* M-x el-get-describe
|
||||
Prompt for a package name, **with completion**, then open an Help window with details about the selected package. Those include current status, website, description,__ installation method__, full recipe, and buttons to easily install, update or remove the package.
|
||||
显示一个package的详细安装、移除、**配置信息**。
|
||||
|
||||
* M-x el-get-install
|
||||
Will prompt for a package name, with completion, then install it. It will only propose packages that are not already installed. Any package that you have a recipe for is a candidate.
|
||||
Please note that when installing a package that is__ not in your el-get-sources or your el-get call means that it will not be initialized__ for you automatically at **emacs startup**. You get a WARNING message when that’s the case.
|
||||
所以,使用el-get-install命令安装的package可能不会被自动配置。需要手动地将它们添加到el-get-sources中。
|
||||
|
||||
* M-x el-get-cd
|
||||
Will prompt for an installed package name, with completion, then open its directory with dired.
|
||||
|
||||
* M-x el-get-update
|
||||
Will prompt for an __installed__ package name, with completion, then update it. This will run the build commands and** init **the package again.
|
||||
|
||||
* M-x el-get-self-update
|
||||
Update only one package, el-get itself.
|
||||
|
||||
* M-x el-get-update-all
|
||||
Will update all packages **used in el-get-sources**. Beware that using this function can lead to hours of settings review: more often than not updating a package requires some adjustments to your setup. Updating all of them at once will require reviewing almost all your setup.
|
||||
|
||||
* M-x el-get-reload
|
||||
Reload the given package files. Happens automatically at update time too.
|
||||
|
||||
* M-x el-get-remove
|
||||
Will prompt for an installed package name, with completion, then remove it. Depending on the type of the package, this often means simply **deleting the directory** where the source package lies. Sometime we have to use external tools instead (apt-get, e.g.). No effort is made to unload the features.
|
||||
|
||||
* M-x el-get-find-recipe-file
|
||||
Will prompt for the name of a package, with completion, then find-file its recipe file.
|
||||
|
||||
* M-x el-get-make-recipes
|
||||
Will prompt for an existing directory where to __output all your new recipe files__: one file for each entry in el-get-sources that is not just a symbol and that is not found anywhere in **el-get-recipe-path**.
|
||||
|
||||
* M-x el-get-checksum
|
||||
Will prompt for the name of an installed package, with complement, then compute its checksum if the **package type supports** that feature. The checksum is __added to the kill-ring__ so that you’re ready to yank it into your el-get-sources :checksum property if you want to.
|
||||
|
||||
* M-x el-get-emacswiki-refresh
|
||||
Will launch a subprocess that connects to EmacsWiki and fetch from there the list of elisp scripts hosted. Then produce a recipe file per script, and store that in the given directory, which default to ~/.emacs.d/el-get/el-get/recipes/emacswiki/ if you didn’t change **el-get-dir**.
|
||||
|
||||
===== Useful functions =====
|
||||
* el-get-package-types-alist (statuses &rest types)
|
||||
Return an alist of package names that are of __given types.__ Only consider packages whose status is **‘member’** of STATUSES, which defaults to installed, required and removed.
|
||||
|
||||
ELISP> (el-get-package-types-alist** "installed" 'cvs 'emacswiki**)
|
||||
((emacs-w3m . cvs)
|
||||
(rect-mark . emacswiki)
|
||||
(icomplete+ . emacswiki)
|
||||
(php-mode-improved . emacswiki)
|
||||
(rainbow-delimiters . emacswiki)
|
||||
(goto-last-change . emacswiki)
|
||||
(emacs-goodies-el . cvs))
|
||||
|
||||
* el-get-extra-packages (&rest packages)
|
||||
Return installed or required packages that **are not **in given package list.
|
||||
|
||||
ELISP> (el-get-extra-packages dim-packages)
|
||||
((verbiste "installed")
|
||||
(package "installed"))
|
||||
|
||||
===== Extending it =====
|
||||
Please see the documentation for the **el-get-methods** and provide a patch!
|
||||
|
||||
Adding __bzr__ support for example was only about writing 2 functions, mostly using copy paste. Here’s the patch: https://github.com/dimitri/el-get/commit/63e9018102bdeb7b6d9136db231adcd983087217#L0R437
|
||||
|
||||
===== Upgrade Notes =====
|
||||
Upgrading to 3.1
|
||||
A change has been included so that el-get-sources is now only another source for recipes, and (el-get '…) will now only install and initialize known "required" and "installed" packages.
|
||||
The documentation has been updated to detail the new setup.
|
||||
If you have packages that have been installed in the past but you no longer want in your setup, here’s how to get them out of the way:
|
||||
M-: (el-get-save-package-status "package-name-here" "removed")
|
||||
Please review documentation section Advanced setup with local recipes.
|
||||
@@ -0,0 +1,86 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:21:50+08:00
|
||||
|
||||
====== Auto-installing packages in Emacs with ELPA and el-get ======
|
||||
Created Saturday 07 January 2012
|
||||
|
||||
http://www.facebook.com/notes/xmms2/auto-installing-packages-in-emacs-with-elpa-and-el-get/10150401940759307
|
||||
|
||||
由 XMMS2 于 2011年8月12日16:05 发布
|
||||
|
||||
Those who live in emacs all know the pain of __manually installing__ extra modes and extensions, especially on different hosts. **System packages** sometimes help, but they differ on every OS (Debian packages, MacPorts, etc.), don’t always exist, and need to be installed manually.
|
||||
|
||||
A better alternative is to__ use emacs itself__ to manage, install and update all the required extra code. The __ELPA project__ provides a way to install packages from different repositories, while __el-get__ can help you declare recipes to install and update code from ELPA, or even Github or Emacswiki.
|
||||
|
||||
First, let’s setup some code that tries to load ELPA and el-get, and installs them if they are not present.
|
||||
|
||||
; derived from ELPA installation
|
||||
; http://tromey.com/elpa/install.html
|
||||
(defun eval-url (url)
|
||||
(let ((buffer (url-retrieve-synchronously url)))
|
||||
(save-excursion
|
||||
(set-buffer buffer)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "^$" nil 'move)
|
||||
(eval-region (point) (point-max))
|
||||
(kill-buffer (current-buffer)))))
|
||||
|
||||
;; Load ELPA
|
||||
(add-to-list 'load-path "~/.emacs.d/elpa")
|
||||
|
||||
(defun install-elpa ()
|
||||
(__eval-url __"http://tromey.com/elpa/package-install.el"))
|
||||
|
||||
(if (__require 'package nil t)__
|
||||
(progn
|
||||
;; Emacs 24+ includes ELPA, but requires some extra setup
|
||||
;; to use the (better) tromey repo
|
||||
(if (>= emacs-major-version 24)
|
||||
(setq package-archives
|
||||
(cons '("tromey" . "http://tromey.com/elpa/")
|
||||
package-archives)))
|
||||
(package-initialize))
|
||||
(install-elpa))
|
||||
|
||||
;; Load el-get
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(defun install-el-get ()
|
||||
(eval-url
|
||||
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"))
|
||||
|
||||
(unless (__require 'el-get nil t__)
|
||||
(install-el-get))
|
||||
|
||||
|
||||
Note that when using** emacs 24, package.el is distributed with emacs** but it points to the GNU package repository; the code above adds tromey’s more complete ELPA repository to the sources.
|
||||
|
||||
Unfortunately, the ELPA installer script **appends a snippet of code to the end of the ~/.emacs** file to **auto-load package.el on startup**. To avoid any problem, it is best to __manually remove__ that code any only keep the load-or-install code above.
|
||||
|
||||
Now that ELPA and el-get are setup, we can **declare all the packages we want installed**. They will be installed after the first time emacs is started, and simply **loaded and initialized** in the future.
|
||||
|
||||
; extra recipes for packages __unknown to el-get__ (yet)
|
||||
(setq el-get-sources
|
||||
'((:name css-mode :type __elpa__)
|
||||
(:name js2-mode-mooz
|
||||
:type git
|
||||
:url "git://github.com/mooz/js2-mode.git"
|
||||
:load "js2-mode.el"
|
||||
:compile ("js2-mode.el")
|
||||
:features js2-mode)))
|
||||
|
||||
; list all packages you want installed
|
||||
(setq my-el-get-packages
|
||||
(append
|
||||
'(css-mode egg gist js2-mode-mooz)
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
(el-get 'sync** my-el-get-packages**)
|
||||
|
||||
|
||||
The el-get 'sync call does all the magic, based on all the packages **past in argument** (as my-el-get-packages). Any packages for which el-get __has a recipe__ can be installed.
|
||||
|
||||
The el-get-sources variable allows to __declare extra custom recipes__ for code to install. In the example above, css-mode is simply pulled from the ELPA repository, while js2-mode-mooz is fetched directly from Github.
|
||||
|
||||
Replicating this code in all your ~/.emacs files is a very easy and convenient way to bootstrap the same emacs environment on multiple hosts.
|
||||
113
Zim/Utils/emacs/el-get/GNU_Emacs的终极扩展管理工具_—_el-get.txt
Normal file
@@ -0,0 +1,113 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:45:05+08:00
|
||||
|
||||
====== GNU Emacs的终极扩展管理工具 — el-get ======
|
||||
Created Saturday 07 January 2012
|
||||
http://emacser.com/el-get.htm
|
||||
|
||||
作者: Nick Qi
|
||||
|
||||
Let’s el-get together
|
||||
|
||||
通常我们在配置GNU Emacs的时候,都会安装一些第三方的lisp扩展来让GNU Emacs用起来更顺手,但是这些第三方lisp扩展的安装、升级和配置的方法各异,通常我们需要使用多种完全不同管理方式的lisp扩展(http直接下载,__发行版包管理器__下载,__版本控制器__下载等)。这样我们升级或者迁移的时候就可能会遇到各种麻烦。
|
||||
|
||||
GNU Emacs一直以来都缺少一个统一的第三方lisp扩展管理器,GNU XEmacs与GNU Emacs的一个区别就是它有一个统一的第三方包管理工具。这其中的原因主要是因为GNU Emacs是GNU Project的一个重要代表,它要求随它发行的所有lisp都__要作者签名用GPL授权给FSF__,但是并不是所有的作者都支持GPL,而且这个过程给第三方贡献增加了不少阻碍。所以当时就有一批开发者开发了GNU XEmacs。所以GNU Emacs一直到现在也没有引入官方的扩展管理工具(指的是当前的稳定版本,ELPA已经被合并到当前的开发分支了)。
|
||||
|
||||
===== 当前第三方包管理方法 =====
|
||||
|
||||
* emacswiki有auto-install.el之类的管理工具
|
||||
* linux发行版的包管理(如debian的lisp包)
|
||||
* tromey写的package.el
|
||||
* 手工使用git之类的版本控制工具来管理lisp扩展
|
||||
* 直接下载
|
||||
|
||||
当前这些方法的不足之处
|
||||
|
||||
* elpa可以管理当前大多数第三方扩展,但是仍然有很多不在里面
|
||||
* 手工管理,升级太麻烦,迁移也不方便
|
||||
* linux发行版的包管理,通常你用不了最新的扩展,而且迁移也挺麻烦
|
||||
* 开发分支的ELPA,不要认为GNU Emacs会放弃原来的授权方式,要进入官方ELPA估计和现在没有什么区别,仍然有很多作者不会把自己的代码交给FSF。不过也会有第三方ELPA。
|
||||
|
||||
===== el-get华丽登场 =====
|
||||
|
||||
=== el-get简介 ===
|
||||
|
||||
* el-get能够透明的管理各种来源的第三方扩展(不管你是通过linux发行版获取,还是直接下载还是通过git等版本控制器获取的)
|
||||
* el-get能够安装,升级和移除它管理的第三方扩展
|
||||
* el-get支持安装后的__初始化__操作,支持hook操作
|
||||
* el-get支持扩展包man和info的安装,安装好后,你可以直接C-h i查看info
|
||||
* el-get的__源描述文件__(recipe)超级简单,可以轻松添加自己的扩展源
|
||||
* el-get支持异步和同步安装和初始化
|
||||
* el-get__支持ELPA__中的所有package安装,ELPA是它的一种安装方法。。。
|
||||
|
||||
===== 安装el-get =====
|
||||
|
||||
el-get的作者参考和ELPA的package.el的做法,使得el-get的安装非常简单:
|
||||
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working el-get.
|
||||
(url-retrieve
|
||||
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp)))
|
||||
|
||||
复制上面的代码到scratch中,移动光标到最后一行结尾,按下C-j然后就可坐等安装完成了。
|
||||
|
||||
===== 使用el-get =====
|
||||
|
||||
el-get的作者是debian developer,所以el-get有深深的apt-get烙印。其实我还觉得el-get很有gentoo portage的影子,直接描述扩展包地址,然后直接下载安装。
|
||||
|
||||
==== 安装扩展 ====
|
||||
|
||||
接下来就是最激动人心的时刻了,让我们先用magit、package和auto-complete来演示el-get的几个功能。
|
||||
|
||||
对于el-get本身,你需要给它手动指定load-path,因为启动的时候需要__先载入它的功能__,然后才能通过它来安装和管理其他lisp扩展。
|
||||
|
||||
当然在你刚安装玩el-get还没有重启GNU Emacs之前,你是可以直接使用它的功能的。
|
||||
|
||||
(setq el-get-sources
|
||||
'(el-get
|
||||
package
|
||||
auto-complete
|
||||
(:name magit
|
||||
__:after__ (lambda () (global-set-key (kbd "C-x C-z") 'magit-status))))
|
||||
)
|
||||
(el-get 'sync)
|
||||
|
||||
复制上面的代码到scratchbuffer,光标移动到buffer最后,键入C-j执行lisp代码。这样el-get、package、auto-complete和magit就被安装到~/.emacs.d/el-get目录下了。而且magit包在安装好后__还执行了__一个按键绑定操作,同样你也可以在任何需要配置的扩展后面__使用定制函数__。
|
||||
|
||||
===== 初始化扩展 =====
|
||||
|
||||
el-get还可以帮助你方便的初始化GNU Emacs扩展,在每个source描诉的__:after__后面可以放上自己的**初始化函数**,就像上面的magit那样。
|
||||
|
||||
通常(el-get)是异步执行的,所以如果你的扩展之间有依赖关系,它的初始化过程可能就会失败,所以为了方便大家写扩展包的初始化函数,作者给(el-get)增加了两种同步
|
||||
方式:
|
||||
|
||||
* (el-get ’sync) 完全同步,初始化的顺序严格按照el-get-sources中的顺序完成
|
||||
* (el-get ‘wait) 初始化过程异步,可以多个source同时初始化,但会等待整个初始化完成
|
||||
|
||||
===== 交互式命令接口 =====
|
||||
|
||||
* el-get-cd 用dired切换到指定package的文件夹
|
||||
* el-get-install 根据用户设定的el-get-sources变量中的package来指定安装其中一个
|
||||
* el-get-update 升级指定的package
|
||||
* el-get-update-all 升级el-get-sources中的所有package,慎用
|
||||
* el-get-remove 删除已经安装而且在el-get-sources中的某个package
|
||||
* 加上C-u前缀的时候,el-get-install和el-get-remove是可以操作仓库中的所有package
|
||||
|
||||
===== 定制和贡献 =====
|
||||
|
||||
* el-get支持本地扩展包仓库,参考el-get-recipe-path变量
|
||||
* 参考package描述文件的文档,对仓库中的package进行定制,可以改变来源、构建命令、 初始化函数。。。
|
||||
* 参考el-get-methods的文档,给el-get增加更多的安装来源支持
|
||||
* 贡献package描述文件(package recipe),添加你喜欢的package
|
||||
* 使用并报告bug,或者要求增加新的特性
|
||||
* 让更多的人用上el-get
|
||||
|
||||
===== 资源和链接 =====
|
||||
|
||||
* el-get github地址: https://github.com/dimitri/el-get
|
||||
* el-get 作者blog: http://tapoueh.org/news.dim.html
|
||||
* 我的el-get分支: https://github.com/vmlinz/el-get
|
||||
44
Zim/Utils/emacs/el-get/blog.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:41:21+08:00
|
||||
|
||||
====== blog ======
|
||||
Created Saturday 07 January 2012
|
||||
|
||||
http://tapoueh.org/emacs/el-get.html
|
||||
|
||||
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want __an easy canonical list of packages I depend on to run emacs__, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
(setq el-get-sources
|
||||
'((:name bbdb
|
||||
:type git
|
||||
:url "git://github.com/barak/BBDB.git"
|
||||
:load-path ("./lisp" "./bits")
|
||||
:info "texinfo"
|
||||
:build ("./configure" "make"))
|
||||
|
||||
(:name magit
|
||||
:type git
|
||||
:url "http://github.com/philjackson/magit.git"
|
||||
:info "."
|
||||
:build ("./autogen.sh" "./configure" "make"))
|
||||
|
||||
(:name vkill
|
||||
:type http
|
||||
:url "http://www.splode.com/~friedman/software/emacs-lisp/src/vkill.el"
|
||||
:features vkill)
|
||||
|
||||
(:name yasnippet
|
||||
:type git-svn
|
||||
:url "http://yasnippet.googlecode.com/svn/trunk/"))
|
||||
|
||||
(setq my-packages
|
||||
(append
|
||||
'(el-get escreen switch-window mailq cssh auto-complete)
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
(el-get 'sync my-packages)
|
||||
|
||||
So now you have a pretty good documentation of the packages__ you want installed__, where to get them, and how to install them. For the advanced methods (such as elpa or apt-get), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the URL to clone and the build steps if any. Then also what features to require and maybe where to find the texinfo documentation of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of all that in a central place, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in__ el-get-dir__) and if that's not the case, it will actually install it. Then, it will init the packages: that means caring about the load-path, the Info-directory-list (and dir texinfo menu building) the loading of the emacs-lisp files, and finally it will require the features.
|
||||
396
Zim/Utils/emacs/el-get/doc.txt
Normal file
@@ -0,0 +1,396 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:54:55+08:00
|
||||
|
||||
====== doc ======
|
||||
Created Saturday 07 January 2012
|
||||
摘自源代码目录中的README文档
|
||||
|
||||
= el-get
|
||||
|
||||
Short Story: el-get allows you to install and manage +elisp+ code for
|
||||
Emacs. It supports lots of __differents types of sources __and is able to
|
||||
'install' them, 'update' them and 'remove' them, but more importantly it
|
||||
will __'init'__ them for you.
|
||||
|
||||
That means it will** +require+** the 'features' you need,** +load+** the
|
||||
necessary files, set the 'Info' paths so that **+C-h i+** shows the new
|
||||
documentation you now depend on, and finally call your own
|
||||
**+:post-init+ **function for you to setup the extension. Or call it a
|
||||
package.
|
||||
|
||||
== Status and Version Numbers
|
||||
|
||||
Current** +el-get+** status is stable, ready for daily use and packed with extra
|
||||
features that make life easier. There are some more things we could do, as
|
||||
always, but they will be about smoothing things further.
|
||||
|
||||
=== Latest released version
|
||||
|
||||
+el-get+ version 2.1 is available, with a boatload of features, including
|
||||
autoloads support, byte-compiling in an external "clean room" Emacs
|
||||
instance, custom support, **lazy initialisation support** (defering all init
|
||||
functions to __+eval-after-load+__), and multi repositories +ELPA+ support.
|
||||
|
||||
=== Version numbering
|
||||
|
||||
Version String are now inspired by how Emacs itself numbers its versions.
|
||||
First is the major version number, then a dot, then the minor version
|
||||
number. The minor version number is 0 when still developping the next major
|
||||
version. So 3.0 is a developer release while 3.1 will be the next stable
|
||||
release.
|
||||
|
||||
Please note that this versioning policy has been picked while backing
|
||||
1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
|
||||
|
||||
== How to Install it?
|
||||
|
||||
Here's the 'lazy installer':
|
||||
|
||||
--------------------------------------
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working el-get.
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp)))
|
||||
--------------------------------------
|
||||
|
||||
You have to type +C-j+ with** the cursor at the end of the last line, but**
|
||||
**still on the line**. 'C-j runs the command eval-print-last-sexp', so it will
|
||||
evaluate the code you're looking at, and that will +git clone el-get+ at the
|
||||
'right place'.
|
||||
|
||||
Note that you can add this elisp code into your __emacs init file__ directly, as
|
||||
the installer code will detect if +el-get+ is already installed. Notice
|
||||
that doing so directly will require internet access to start emacs. You can
|
||||
avoid this with the following snippet instead:
|
||||
|
||||
--------------------------------------
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless __(require 'el-get nil t)__
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
--------------------------------------
|
||||
|
||||
See next section for details about how to** setup you emacs** so that it's able
|
||||
to benefit from +el-get+ automatically.
|
||||
|
||||
== How to install the developer version (master branch)?
|
||||
|
||||
The 'lazy installer' uses the default +el-get-install.el+ file which targets
|
||||
the +2.stable+ branch. To install el-get directly on the +master+ branch,
|
||||
summon the +el-get-master-branch+ variable into existence:
|
||||
|
||||
--------------------------------------
|
||||
;; So the idea is that you copy/paste this code into your *scratch* buffer,
|
||||
;; hit C-j, and you have a working developper edition of el-get.
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(let (el-get-master-branch)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
--------------------------------------
|
||||
|
||||
== Basic usage
|
||||
|
||||
Now that +el-get+ is installed, simply use **+M-x el-get-install+** and pick
|
||||
whatever package you need. __ Arrange to__ have +el-get+ part of your setup, so
|
||||
that at next emacs startup the installed packages are **initialized**. Here's
|
||||
how to:
|
||||
通过el-get-install命令安装的package,需要在el-get的配置文件中添加一些设置,这样
|
||||
emacs下次启动时,el-get才会__自动地配置__它们。
|
||||
--------------------------------------
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless (require 'el-get nil t)
|
||||
(url-retrieve
|
||||
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
|
||||
(el-get 'sync)
|
||||
--------------------------------------
|
||||
|
||||
That's the basic setup.
|
||||
|
||||
== Advanced setup with local recipes
|
||||
|
||||
Of course, my emacs setup is managed in a private git repository. Some
|
||||
people on +#emacs+ are using +git submodules+ (or was it straight import)
|
||||
for managing external repositories in there, but all I can say is that I
|
||||
frown on this idea. I want an easy canonical list of packages I depend on to
|
||||
run emacs, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
--------------------------------------
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
(require 'el-get)
|
||||
|
||||
;; local sources
|
||||
(setq __el-get-sources__
|
||||
'((:name magit
|
||||
:after (lambda () (global-set-key (kbd "C-x C-z") 'magit-status)))
|
||||
|
||||
(:name asciidoc
|
||||
:type elpa
|
||||
:after (lambda ()
|
||||
(autoload 'doc-mode "doc-mode" nil t)
|
||||
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
|
||||
(add-hook 'doc-mode-hook '(lambda ()
|
||||
(turn-on-auto-fill)
|
||||
(require 'asciidoc)))))
|
||||
|
||||
(:name lisppaste :type elpa)
|
||||
(:name dictionary-el :type apt-get)
|
||||
(:name emacs-goodies-el :type apt-get)))
|
||||
|
||||
(setq __my-packages__
|
||||
(append
|
||||
'(cssh el-get switch-window vkill google-maps nxhtml xcscope yasnippet)
|
||||
(mapcar 'el-get-source-name el-get-sources)))
|
||||
|
||||
__(el-get 'sync my-packages)__
|
||||
--------------------------------------
|
||||
|
||||
So now you have a pretty good documentation of the packages you want
|
||||
installed, where to get them, and how to install them. For the advanced
|
||||
methods (such as elpa or apt-get), you basically just need the package
|
||||
name. When relying on a bare git repository, you need to give some more
|
||||
information, such as the URL to clone and the build steps if any. Then also
|
||||
what features to require and maybe where to find the texinfo documentation
|
||||
of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of
|
||||
all that in a central place, but this very description is all (el-get) needs
|
||||
to do its magic. This command will check that each and every package is
|
||||
installed on your system (in __el-get-dir__) and if that's not the case, it will
|
||||
actually install it. Then, it will__ init the packages__: that means caring
|
||||
about the load-path, the Info-directory-list (and dir texinfo menu building)
|
||||
the loading of the emacs-lisp files, and finally it will require the
|
||||
features.
|
||||
|
||||
== How to use it?
|
||||
|
||||
You see that +el-get-sources+ example up there? It __finishes with a single__
|
||||
__+(el-get)+ call__. That's it. It will 'install' new +sources+ on the list and
|
||||
only 'init' already installed ones.
|
||||
|
||||
The status of each package is tracked into +~/.emacs.d/el-get/__.status.el__+
|
||||
(by default) and can get the values +required+, +installed+ or +removed+.
|
||||
|
||||
=== Sync or async?
|
||||
|
||||
Most often you want +el-get-install+ and +el-get-build+ to stay out of the
|
||||
way and be 'asynchronous', so that you can continue using Emacs while your
|
||||
new package is getting ready. But imagine you're starting up Emacs after a
|
||||
+git pull+ on the other computer (after a commute, say), and there's some
|
||||
newer packages for this instance to consider installing.
|
||||
|
||||
Now you want a synchronous install, right?
|
||||
|
||||
So, by default +(el-get)+ is asynchronous, but you can ask for it to be
|
||||
sync, or to still be asynchronous but to wait until it finished before to
|
||||
give control back:
|
||||
|
||||
(el-get 'sync)
|
||||
(el-get 'wait)
|
||||
|
||||
You even get a progress report!
|
||||
|
||||
=== Sources
|
||||
|
||||
See the documentation of the +el-get-sources+ variable for details. __Please__
|
||||
__note that +el-get-sources+ is another source location for recipes, adding to__
|
||||
__your +el-get-recipe-path+.__
|
||||
|
||||
Note that you can also give a mix of +packages+ symbols, +inline recipes+
|
||||
and +source lists+ to +el-get+ as arguments, and completely __bypass__ the
|
||||
+el-get-sources+ variable.
|
||||
|
||||
(el-get 'sync 'package 'name 'list-of-packages-names-or-symbol)
|
||||
|
||||
It is still __recommended__ to +(setq el-get-sources '(list of packages))+ then
|
||||
use +(el-get 'sync)+, so that commands such as +el-get-update+ know which
|
||||
packages to update.
|
||||
|
||||
=== Recipes
|
||||
|
||||
Some sources are contributed to +el-get+ directly, so that you only have to
|
||||
put in the +el-get-sources+ the name of the package you want to
|
||||
install.
|
||||
|
||||
Should you need some __local specific setup__, you can do that by providing a
|
||||
partial sources **missing the +:type+ property**: your local properties will get
|
||||
merged into the recipes one.
|
||||
|
||||
Also, the variable __+el-get-recipe-path+__ allows you to maintain local recipes
|
||||
in case you either dislike the default one or are crafting some new one not
|
||||
commited to the main repository yet. But please do consider sending them
|
||||
over!
|
||||
|
||||
We do not intend to provide recipes for advanced types such as +apt-get+ and
|
||||
+elpa+ because there's so little to win here, and maintaining a package list
|
||||
would take too much time.
|
||||
|
||||
=== Package setup
|
||||
|
||||
The package setup can either go into the __+:after+__ function, or in a file
|
||||
named __+init-package.el+ in +el-get-user-package-directory+__. Any such named
|
||||
file will get automatically loaded by +el-get+ at +init+ time, if it exists.
|
||||
|
||||
=== Build Commands
|
||||
|
||||
__Avoid using +make install+__, which will usually move files into a
|
||||
"system location." In our case, you probably just want your package
|
||||
+foo+ to be all installed into +~/.emacs.d/el-get/foo+, right? So, no
|
||||
+make install+.
|
||||
|
||||
=== Byte Compiling
|
||||
|
||||
+el-get+ will 'byte compile' the elisp for the package when its source
|
||||
definition includes a +:compile+ property set to the list of files to byte
|
||||
compile (or to a single file), or all the +.el+ files found in the package
|
||||
when there's no +:build+ command.
|
||||
|
||||
=== Hooks
|
||||
|
||||
+el-get+ offers a variety of specific hooks (read the source), and two
|
||||
general purposes hooks facilities: +el-get-post-install-hooks+ and
|
||||
+el-get-post-update-hooks+, called with the package name as argument.
|
||||
|
||||
=== Some more commands?
|
||||
|
||||
Yes, ok.
|
||||
|
||||
M-x el-get-list-packages::
|
||||
|
||||
Opens a buffer listing all known packages (those for which you have a
|
||||
recipe). The listing includes the package name, its status (one of
|
||||
"available", "installed", "removed" or "required") and the package
|
||||
description. The description is a free form text and has not been
|
||||
provided for all recipes. Please also note that
|
||||
+el-get-emacswiki-refresh+ will create recipes omitting the description
|
||||
as of now.
|
||||
|
||||
M-x el-get-describe::
|
||||
|
||||
Prompt for a package name, with completion, then open an +*Help*+ window
|
||||
with details about the selected package. Those include current status,
|
||||
website, description, installation method, full recipe, and buttons to
|
||||
easily install, update or remove the package.
|
||||
|
||||
M-x el-get-install::
|
||||
+
|
||||
Will prompt for a package name, with completion, then install it. It will
|
||||
only propose packages that are not already +installed+. Any package that
|
||||
you have a recipe for is a candidate.
|
||||
+
|
||||
Please note that when installing a package that is not in your
|
||||
+el-get-sources+ or your +el-get+ call means that it will not be initialized
|
||||
for you automatically at emacs startup. You get a +WARNING+ message when
|
||||
that's the case.
|
||||
|
||||
M-x el-get-cd::
|
||||
|
||||
Will prompt for an +installed+ package name, with completion, then open
|
||||
its directory with dired.
|
||||
|
||||
M-x el-get-update::
|
||||
|
||||
Will prompt for an installed package name, with completion, then update
|
||||
it. This will run the +build+ commands and +init+ the package again.
|
||||
|
||||
M-x el-get-self-update::
|
||||
|
||||
Update only one package, +el-get+ itself.
|
||||
|
||||
M-x el-get-update-all::
|
||||
|
||||
Will update all packages used in +el-get-sources+. Beware that using
|
||||
this function can lead to hours of settings review: more often than not
|
||||
updating a package requires some adjustments to your setup. Updating
|
||||
all of them at once will require reviewing almost all your setup.
|
||||
|
||||
M-x el-get-remove::
|
||||
|
||||
Will prompt for an +installed+ package name, with completion, then
|
||||
remove it. Depending on the +type+ of the package, this often means
|
||||
simply deleting the directory where the source package lies. Sometime we
|
||||
have to use external tools instead (+apt-get+, e.g.). No effort is made
|
||||
to unload the features.
|
||||
|
||||
M-x el-get-find-recipe-file::
|
||||
|
||||
Will prompt for the name of a package, with completion, then +find-file+
|
||||
its +recipe+ file.
|
||||
|
||||
M-x el-get-make-recipes::
|
||||
|
||||
Will prompt for an existing directory where to output all your 'new'
|
||||
recipe files: one file for each entry in +el-get-sources+ that is not
|
||||
just a +symbol+ and that is not found anywhere in +el-get-recipe-path+.
|
||||
|
||||
M-x el-get-emacswiki-refresh::
|
||||
|
||||
Will launch a subprocess that connects to EmacsWiki and fetch from there
|
||||
the list of elisp scripts hosted. Then produce a recipe file per
|
||||
script, and store that in the given directory, which default to
|
||||
+~/.emacs.d/el-get/el-get/recipes/emacswiki/+ if you didn't change
|
||||
+el-get-dir+.
|
||||
|
||||
=== Useful functions
|
||||
|
||||
el-get-package-types-alist (statuses &rest types)::
|
||||
|
||||
Return an alist of package names that are of given types. Only consider
|
||||
packages whose status is `member' of STATUSES, which defaults to
|
||||
installed, required and removed.
|
||||
|
||||
ELISP> (el-get-package-types-alist "installed" 'cvs 'emacswiki)
|
||||
((emacs-w3m . cvs)
|
||||
(rect-mark . emacswiki)
|
||||
(icomplete+ . emacswiki)
|
||||
(php-mode-improved . emacswiki)
|
||||
(rainbow-delimiters . emacswiki)
|
||||
(goto-last-change . emacswiki)
|
||||
(emacs-goodies-el . cvs))
|
||||
|
||||
el-get-extra-packages (&rest packages)::
|
||||
|
||||
Return installed or required packages that are not in given package
|
||||
list.
|
||||
|
||||
ELISP> (el-get-extra-packages dim-packages)
|
||||
((verbiste "installed")
|
||||
(package "installed"))
|
||||
|
||||
== Extending it
|
||||
|
||||
Please see the documentation for the +el-get-methods+ and provide a patch!
|
||||
|
||||
Adding +bzr+ support for example was only about writing 2 functions, mostly
|
||||
using copy paste. Here's the patch: https://github.com/dimitri/el-get/commit/63e9018102bdeb7b6d9136db231adcd983087217#L0R437
|
||||
|
||||
== Upgrade Notes
|
||||
|
||||
=== Upgrading to 3.1
|
||||
|
||||
A change has been included so that +el-get-sources+ is now __only another__
|
||||
__source for recipes__, and +(el-get '...)+ will now only install and initialize
|
||||
known "required" and "installed" packages.
|
||||
|
||||
The documentation has been updated to detail the new setup.
|
||||
|
||||
If you have packages that have been installed in the past but you no longer
|
||||
want in your setup, here's how to get them out of the way:
|
||||
|
||||
M-: (el-get-save-package-status "package-name-here" "removed")
|
||||
|
||||
Please review documentation section 'Advanced setup with local recipes'.
|
||||
143
Zim/Utils/emacs/el-get/emacsWiki.txt
Normal file
@@ -0,0 +1,143 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T15:04:30+08:00
|
||||
|
||||
====== emacsWiki ======
|
||||
Created Saturday 07 January 2012
|
||||
http://www.emacswiki.org/emacs/el-get#toc3
|
||||
|
||||
===== Contenus =====
|
||||
|
||||
Emacs Lisp get (Fetch, Install, Update, etc)
|
||||
Why el-get?
|
||||
How is el-get different from ELPA?
|
||||
Why have both?
|
||||
Social Packaging
|
||||
el-get and emacswiki
|
||||
emacs-kicker
|
||||
|
||||
===== Emacs Lisp get (Fetch, Install, Update, etc) =====
|
||||
El-get is tool that allows downloading **external scripts/extensions **for Emacs, __install __them for you, knows how to __update__ them and __init__ them, care about **load-path** and **Info-directory-list**, **byte-compile** what should be, manages **autoloads**, etc.
|
||||
JohnWiegley once said “el-get seems like it’s the Great Unifier of Emacs package systems and package repositories”
|
||||
Think apt-get for Emacs, and check out el-get.
|
||||
|
||||
===== Why el-get? =====
|
||||
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy **canonical list of packages **I depend on to run Emacs, and I want this documentation to be usable as-is. Enters el-get!
|
||||
|
||||
The following is an example of how to use it in your __.emacs__, you could also consider starting from the **emacs-kicker**.
|
||||
|
||||
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
|
||||
|
||||
(unless (__require 'el-get nil t__)
|
||||
(url-retrieve
|
||||
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
|
||||
(lambda (s)
|
||||
(end-of-buffer)
|
||||
(eval-print-last-sexp))))
|
||||
|
||||
;; now either el-get is `require'd __already__, or have been `load'ed by the
|
||||
;; el-get installer.
|
||||
(setq
|
||||
** el-get-sources**
|
||||
'(el-get ; el-get is self-hosting
|
||||
escreen ; screen for emacs, C-\ C-h
|
||||
php-mode-improved ; if you're into php...
|
||||
switch-window ; takes over C-x o
|
||||
auto-complete ; complete as you type with overlays
|
||||
zencoding-mode ; http://www.emacswiki.org/emacs/ZenCoding
|
||||
|
||||
(:name buffer-move ; have to add your own keys
|
||||
:after (lambda ()
|
||||
(global-set-key (kbd "<C-S-up>") 'buf-move-up)
|
||||
(global-set-key (kbd "<C-S-down>") 'buf-move-down)
|
||||
(global-set-key (kbd "<C-S-left>") 'buf-move-left)
|
||||
(global-set-key (kbd "<C-S-right>") 'buf-move-right)))
|
||||
|
||||
(:name smex ; a better (ido like) M-x
|
||||
:after (lambda ()
|
||||
(setq smex-save-file "~/.emacs.d/.smex-items")
|
||||
(global-set-key (kbd "M-x") 'smex)
|
||||
(global-set-key (kbd "M-X") 'smex-major-mode-commands)))
|
||||
|
||||
(:name magit ; __git__ meet emacs, and a binding
|
||||
:after (lambda ()
|
||||
(global-set-key (kbd "C-x C-z") 'magit-status)))
|
||||
|
||||
(:name goto-last-change ; move pointer back to last change
|
||||
:after (lambda ()
|
||||
;; when using AZERTY keyboard, consider C-x C-_
|
||||
(global-set-key (kbd "C-x C-/") 'goto-last-change)))))
|
||||
|
||||
(unless (string-match "**apple-darwin**" system-configuration)
|
||||
(loop for p in '(color-theme ; nice looking emacs
|
||||
color-theme-tango ; check out color-theme-solarized
|
||||
)
|
||||
do (add-to-list 'el-get-sources p)))
|
||||
|
||||
;;
|
||||
;; Some recipes require __extra tools__ to be installed
|
||||
;;
|
||||
;; Note: el-get-install requires **git**, so we know we have at least that.
|
||||
;;
|
||||
(when (el-get-executable-find "cvs")
|
||||
(add-to-list 'el-get-sources 'emacs-goodies-el)) ; the debian addons for emacs
|
||||
|
||||
(when (el-get-executable-find "svn")
|
||||
(loop for p in '(psvn ; M-x svn-status
|
||||
yasnippet ; powerful snippet mode
|
||||
)
|
||||
do (add-to-list 'el-get-sources p)))
|
||||
|
||||
;; install new packages and init already installed packages
|
||||
(el-get 'sync)
|
||||
|
||||
So now you have a pretty good documentation of the packages__ you want installed__, **where** to get them, and **how** to install them. For the advanced methods (such as **ELPA or apt-get**), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the **URL** to clone and the build steps if any. Then also what** features** to require and maybe where to find the **texinfo **documentation of the package, for automatic inclusion into your local Info menu.
|
||||
|
||||
The good news is that not only you now have a solid readable description of __all that in a central place__, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in el-get-dir) and if that’s not the case, it will actually install it. Then, it will__ init __the packages: that means caring about the** load-path**, the Info-directory-list (and dir texinfo menu building) the loading of the **EmacsLisp files**, and finally it will **require** the features.
|
||||
|
||||
===== How is el-get different from ELPA? =====
|
||||
ELPA is the** Emacs Lisp Package Archive** and is also known as__ package.el__, to be included in Emacs 24. This allows emacs list extension authors to package their work. That means they have to follow some guidelines and format their contribution, then propose it for upload.
|
||||
|
||||
This requires licence checks (good) and for the new official ELPA mirror it even requires dead-tree papers exchange and contracts and copyright assignments, I believe.
|
||||
|
||||
===== Why have both? =====
|
||||
While ELPA is a great thing to have, it’s so easy to find some high quality Emacs extension out there that are not part of the offer. Either authors are not interrested into uploading to ELPA, or they don’t know how to properly package for it (it’s only simple for single file extensions, see).
|
||||
|
||||
So el-get is a pragmatic answer here. It’s there because it so happens that I don’t depend only on emacs extensions that are available with Emacs itself, in my distribution site-lisp and in ELPA. I need some more, and I don’t need it to be complex to find it, fetch it, init it and use it.
|
||||
|
||||
Of course I could try and package any extension I find I need and submit it to ELPA, but really, to do that nicely I’d need to contact the extension author (upstream) for him to accept my patch, and then consider a fork.
|
||||
|
||||
===== Social Packaging =====
|
||||
With el-get I propose distributed packaging if you will. Let’s have a look at __two recipes(菜单)__ here. First, the el-get one itself:
|
||||
|
||||
(:name el-get
|
||||
:type git
|
||||
:url "git://github.com/dimitri/el-get.git"
|
||||
:features el-get
|
||||
:compile "el-get.el")
|
||||
|
||||
Then a much more complex one, the bbdb one:
|
||||
|
||||
(:name bbdb
|
||||
:type git
|
||||
:url "git://github.com/barak/BBDB.git"
|
||||
:load-path ("./lisp" "./bits")
|
||||
:build ("./configure" "make autoloads" "make")
|
||||
:build/darwin ("./configure --with-emacs=/Applications/Emacs.app/Contents/MacOS/Emacs" "make autoloads" "make")
|
||||
:features bbdb
|
||||
:after (lambda () (bbdb-initialize))
|
||||
:info "texinfo")
|
||||
|
||||
The idea is that it’s __much simpler __to just come up with a recipe like this than to patch existing code and upload it to ELPA. And anybody can share their recipes very easily, with or without proposing them to me, even if I very much like to add some more in the official el-get list.
|
||||
|
||||
As a user, you don’t even need to twiddle with recipes, mostly, because we **already have them** for you. What you do instead is __list them in el-get-sources__.
|
||||
|
||||
===== el-get and emacswiki =====
|
||||
Just run **M-x el-get-emacswiki-refresh** and you will have a local cache of recipes for all scripts available in EmacsWiki. Now you can M-x el-get-install any of them, it’s a single command away.
|
||||
|
||||
===== emacs-kicker =====
|
||||
Following up on the very popular **emacs-starter-kit**, I’m now proposing the emacs-kicker. It’s about a very simple __.emacs__ file using el-get. It comes with an arbitrary selection of packages that make your life easier, and with some medium advanced settings. The idea is to, well, kick start you.
|
||||
https://github.com/dimitri/emacs-kicker
|
||||
|
||||
If you want to try it without installing it it’s very easy to do so. Just clone the git repository then start an Emacs that will use this. For example that could be, using the excellent Emacs For MacOSX:
|
||||
$ /Applications/Emacs.app/Contents/MacOS/Emacs -Q -l init.el
|
||||
203
Zim/Utils/emacs/el-get/配置.txt
Normal file
@@ -0,0 +1,203 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-01-07T16:25:55+08:00
|
||||
|
||||
====== 配置 ======
|
||||
Created Saturday 07 January 2012
|
||||
|
||||
**El Get Sources**: Show Value
|
||||
State: HIDDEN, invoke "Show" in the previous line to show.
|
||||
|
||||
Each entry is a PLIST where the following properties are
|
||||
supported.
|
||||
|
||||
If your property list is missing the :type property, then it's
|
||||
__merged__ with the recipe one, so that you can** override **any
|
||||
definition provided by `el-get' recipes locally.
|
||||
|
||||
:name
|
||||
|
||||
The name of the package. It can be different from the name of
|
||||
the directory where the package is stored (after a `git
|
||||
clone' for example, in which case a symlink will be created.
|
||||
|
||||
:depends
|
||||
|
||||
A single package name, or a list of package names, on which
|
||||
the package depends. All of a packages dependencies will be
|
||||
installed before the package is installed.
|
||||
|
||||
:pkgname
|
||||
|
||||
The name of the package for the __underlying package management__
|
||||
__system__ (`apt-get', `fink' or `**pacman**', also supported by
|
||||
`emacsmirror'), which can be different from the Emacs package
|
||||
name.
|
||||
|
||||
:type
|
||||
|
||||
The type of the package, currently el-get offers support for
|
||||
`apt-get', `elpa', `git', `emacsmirror', `git-svn', `bzr' `svn',
|
||||
`cvs', `darcs', `fink', `ftp', `emacswiki', `http-tar', __`pacman'__,
|
||||
`hg' and `http'. You can easily support your own types here,
|
||||
see the variable `el-get-methods'.
|
||||
|
||||
:branch
|
||||
|
||||
Which branch to fetch when using `git'. Also supported in
|
||||
the installer in `el-get-install'.
|
||||
|
||||
:url
|
||||
|
||||
Where to fetch the package, only meaningful for `git' and `http' types.
|
||||
|
||||
:build
|
||||
|
||||
Your build recipe, a list.
|
||||
|
||||
A recipe R whose `car' is not a string will be replaced
|
||||
by (eval R).
|
||||
|
||||
Then, each element of the recipe will be interpreted as
|
||||
a command:
|
||||
|
||||
* If the element is a string, it will be interpreted directly
|
||||
by the shell.
|
||||
|
||||
* Otherwise, if it is a list, any list sub-elements will be
|
||||
recursively "flattened" (see `el-get-flatten'). The
|
||||
resulting strings will be interpreted as individual shell
|
||||
arguments, appropriately quoted.
|
||||
|
||||
:build/system-type
|
||||
|
||||
Your specific build recipe for a given `system-type' gets
|
||||
there and looks like :build.
|
||||
|
||||
:load-path
|
||||
|
||||
A directory or a list of directories you want `el-get' to add
|
||||
to your **`load-path'**. Those directories are__ relative to__ where
|
||||
the package gets installed.
|
||||
|
||||
:compile
|
||||
|
||||
Allow to restrict what to byte-compile: by default, `el-get'
|
||||
will compile __all elisp files in the :load-path directories__,
|
||||
unless a :build command exists for the package source. Given
|
||||
a :compile property, `el-get' will only byte-compile those
|
||||
**given files**, directories or __filename-regexpes__ in the property
|
||||
value. This property can be a `listp' or a `stringp' if you
|
||||
want to compile only one of those.
|
||||
|
||||
:info
|
||||
|
||||
This string allows you to setup a __directory__ where to find a
|
||||
'package.info' file, or a path/to/whatever.info file. It will
|
||||
even run `ginstall-info' for you to create the `dir' entry so
|
||||
that C-h i will be able to list the newly installed
|
||||
documentation. Note that you might need to kill (C-x k) your
|
||||
info buffer then C-h i again to be able to see the new menu
|
||||
entry.
|
||||
|
||||
:load
|
||||
|
||||
List of files to load, or a single file to load after having
|
||||
installed the source but __before__ `require'ing its features.
|
||||
|
||||
:features
|
||||
|
||||
List of features el-get will __`require'__ for you.
|
||||
|
||||
:autoloads
|
||||
|
||||
Control whether el-get should generate autoloads for this
|
||||
package. Setting this to nil prevents el-get from generating
|
||||
autoloads for the package. __Default is t__. Setting this to a
|
||||
string or a list of string will load the named autoload
|
||||
files.
|
||||
|
||||
:library
|
||||
|
||||
When **using :after but not using :features, **:library allows to
|
||||
set the library against which to register the :after function
|
||||
against `eval-after-load'. It defaults to either :pkgname
|
||||
or :package, in this order. See also `el-get-eval-after-load'.
|
||||
|
||||
:options
|
||||
|
||||
Currently used by http-tar and cvs support.
|
||||
|
||||
When using http-tar, it allows you to give the tar options
|
||||
you want to use. Typically would be "xzf", but you might
|
||||
want to choose "xjf" for handling .tar.bz files e.g.
|
||||
|
||||
When using CVS, when it's set to "login", `el-get' will
|
||||
first issue a `cvs login' against the server, asking you
|
||||
interactively (in the minibuffer) any password you might to
|
||||
enter, and only then it will run the `cvs checkout' command.
|
||||
|
||||
:module
|
||||
|
||||
Currently only used by the `cvs' support, allow you to
|
||||
configure the module you want to checkout in the given URL.
|
||||
|
||||
:repo
|
||||
|
||||
Only used by the `elpa' support, a cons cell with the
|
||||
form (NAME . URL), as in `package-archives'. If the package
|
||||
source only specifies a URL, the URL will be used for NAME as
|
||||
well.
|
||||
|
||||
:prepare
|
||||
|
||||
Intended for use __from recipes__, it will run once both the
|
||||
**`Info-directory-list' and the**__ `load-path' __**variables have been**
|
||||
** taken care of**, but before any further action from
|
||||
`el-get-init'.
|
||||
|
||||
:before
|
||||
|
||||
A pre-init function to run once__ before__** `el-get-init' calls**
|
||||
** `load' and `require'. ** It gets to run with `load-path'
|
||||
already set, and after :prepare has been called. It's__ not__
|
||||
__ intended__ for use from recipes.
|
||||
|
||||
:post-init
|
||||
|
||||
Intended for use from recipes. This function is registered
|
||||
for __`eval-after-load'__ against the recipe library by
|
||||
`el-get-init' once the **:load and :features** have been setup.
|
||||
|
||||
:after
|
||||
|
||||
A function to register for `eval-after-load' against the
|
||||
recipe library, after :post-init, and __after per-package__
|
||||
__ user-init-file (see `el-get-user-package-directory'). __ That's not
|
||||
intended for recipe use.
|
||||
|
||||
:lazy
|
||||
|
||||
Default to nil. Allows to override `el-get-is-lazy' per
|
||||
package.
|
||||
|
||||
:localname
|
||||
|
||||
Currently only used by both `http' and `ftp' supports, allows
|
||||
to specify the target name of the downloaded file.
|
||||
|
||||
This option is useful if the package should be retrieved using
|
||||
a presentation interface (such as as web SCM tool).
|
||||
|
||||
For example, destination should be set to "package.el" if
|
||||
the package url has the following scheme:
|
||||
|
||||
"http://www.example.com/show-as-text?file=path/package.el"
|
||||
|
||||
:website
|
||||
|
||||
The website of the project.
|
||||
|
||||
:description
|
||||
|
||||
A short description of the project.
|
||||
423
Zim/Utils/emacs/emacs国际化.txt
Normal file
@@ -0,0 +1,423 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-08-19T17:08:58+08:00
|
||||
|
||||
====== emacs国际化 ======
|
||||
Created Friday 19 August 2011
|
||||
http://www.linuxsir.org/bbs/showthread.php?t=237956
|
||||
|
||||
** 国际化(International): 使用非 ASCII 字符集(MULE 特性)
|
||||
....
|
||||
|
||||
|
||||
|
||||
国际字符集支持
|
||||
|
||||
Emacs 支持的__国际字符集__范围很广,从拉丁字母表的欧洲变体,到中文、西里尔字母(Cyrillic)、梵文(北印度语(Hindi)和马拉地语(Marathi))、埃塞俄比亚文、希腊文、希伯来文、国际音标(IPA)、日本语、朝鲜文字、老挝,泰和越南语文,还有藏文。这些支持都集中在 Emacs 的被称为 __MULE__(MULti-lingual Enhancement to GNU Emacs, GNU Emacs 的多语言无敌版) 的修改版本中。
|
||||
|
||||
Emacs 也支持这些字符的__各种编码__,它们用在其它国际化软件,类似字处理程序以及邮件程序中。
|
||||
|
||||
Emacs 支持下列相关操作,从而实现了包含国际字符的文本编辑:
|
||||
|
||||
- 您可以查看包含非 ASCII 字符的文件,保存非 ASCII 文本,在 Emacs 和它启动的程序(例如编译器、拼写检查程序和邮件程序等等)之间传递非 ASCII 文本。设置__语言环境__(参见语言环境)的时候,编码系统以及与特定语言或文化相关的变量都将自动得到设置。或者,您也可以指定 Emacs 在编码和解码每个程序的文本时的方式(参见指定编码)。
|
||||
|
||||
- 您可以显示每种文字 (script) 包含的非 ASCII 字符。实现方式是通过在 X 和类似的图形环境中,使用合适的字体(参见定义字体集),以及在文本终端下,发送特殊的代码(参见指定编码)。如果某些字符显示不正常,参见无法显示的字符,那里记载了可能的问题以及解决的办法。
|
||||
|
||||
- 您可以插入非 ASCII 字符,或者搜索它们。为此,您可以指定一种适于您的语言的输入法(参见选择输入法),或者使用您的语言环境加载时设定的默认输入法。(Emacs 输入法是 Leim 软件包的一部分,它必须安装才能使用。)如果您的键盘可以产生非 ASCII 字符,您可以设置合适的键盘编码系统(参见指定编码),然后 Emacs 就可以接受那些字符了。Latin-1 字符也可以使用 C-x 8 前缀输入,参见单字节字符集支持。在 X 窗口系统中,您的语言环境变量(__locale__)必须设置为合适的值,Emacs 才能正确解释键盘输入,参见语言环境。
|
||||
|
||||
本章的其余部分将详细描述下列主题。
|
||||
|
||||
* 国际字符: 多字节字符的基本概念
|
||||
* 使用多字节字符: 控制是否使用多字节字符
|
||||
* 语言环境: 为您使用的语言进行设置
|
||||
* 输入法: 输入未标示在键盘上的文字字符
|
||||
* 选择输入法: 指定您选用的输入法
|
||||
* 多字节转换: 单字节字符如何转换为多字节
|
||||
* 编码系统: 当您读写文件时的字符集转换,以及其他
|
||||
* 识别编码: Emacs 如何推断必需的转换
|
||||
* 指定编码: 各种设定转换的方法
|
||||
* 字体集: 字体集是覆盖所有字符的字体集合
|
||||
* 定义字体集: 定义新的字体集
|
||||
* 无法显示的字符: 当字符无法显示的时候
|
||||
* 单字节字符集支持: 无需多字节字符,您也可以选用一种西欧字符集
|
||||
|
||||
国际字符
|
||||
|
||||
国际字符集和文字的用户建立了很多或多或少称得上标准的编码系统来保存文件。Emacs 内部使用单一的多字节字符编码,因此可以在一个缓冲区或字符串中混合所有文字的字符。这个编码将每个非 ASCII 字符表示为 0200 到 0377 的字节序列。在读写文件的时候,与子进程交换数据的时候,以及有时在 C-q 命令中,Emacs 在多字节字符编码和各种其他编码系统间转换(参见多字节转换)。
|
||||
|
||||
命令 C-h h(view-hello-file) 显示文件 etc/HELLO,它显示了如何在各种语言中表达"你好"。它展示了多种文字。如果终端上无法显示一些字符,它们将显示为 '?' 或中空的方块(参见无法显示的字符)。
|
||||
|
||||
键盘通常不会为一个字符集的所有字符提供按键,即使在使用这个字符集的国家也是如此。因此 Emacs 支持多种 输入法,通常每种文字或语言都有一种,来方便地输入它们。
|
||||
|
||||
按键前缀 C-x <RET> 用于附属于多字节字符支持,编码系统以及输入法的命令。
|
||||
|
||||
使用多字节字符
|
||||
|
||||
您可以启用或禁用整个 Emacs 的多字节字符支持,也可以只设置单个缓冲区。如果缓冲区禁用多字节字符,那么每个字节就代表一个字符,即使 0200 到 0377 之间的码点也不例外。这样做来支持欧洲字符集,ISO Latin-1 和 ISO Latin-2 的做法与 Emacs 19 中类似,其他 ISO 8859 字符集也是如此。
|
||||
|
||||
但是,不必关闭多字节字符支持也可以使用 ISO Latin 字符集;Emacs 多字节字符集包含了这些字符集中所有字符,并且 Emacs 可以自由地与 ISO 编码转换。
|
||||
|
||||
默认情况下,Emacs 启动是多字节模式,因为这样您可以没有限制地使用所有支持的语言和文字。
|
||||
|
||||
要在单字节方式下编辑某个文件,用 find-file-literally 打开文件,参见察看。要将多字节的缓冲区转换为相同字符的单字节表示,最简单的办法是将缓冲区保存为文件,关闭缓冲区,然后再次用 find-file-literally 打开文件。您也可以用 C-x <RET> c(universal-coding-system-argument) 命令,并且指定 'raw-text' 作为打开和保存文件时的编码系统。以 'raw-text' 打开文件不会禁止格式转换、解压缩和自动模式切换,而 find-file-literally 会禁止它们。
|
||||
|
||||
要关闭多字节字符集支持,启动 Emacs 时候加上 '--unibyte' 参数(参见初始化参数),或者设置环境变量 EMACS_UNIBYTE。您也可以在初始化文件中定制 enable-multibyte-characters 或等价地,直接设置变量 default-enable-multibyte-characters 为 nil,来得到与 '--unibyte' 同样的效果。
|
||||
|
||||
要将单字节的会话转换为多字节,设置 default-multibyte-characters 为 t。在转换前创建的单字节缓冲区仍然会保持单字节。您可以在缓冲区中执行 toggle-enable-multibyte-characters 来打开这个缓冲区的多字节支持。
|
||||
|
||||
如果有 '--unibyte' 选项,根据包含非 ASCII 8-bit 字符的环境变量和 /etc/passwd 条目初始化的时候就不会创建多字节字符串。
|
||||
|
||||
Emacs 通常以多字节方式加载 Lisp 文件,无论是否使用了 '--unibyte'。这也包括初始化文件 .emacs,以及 Emacs 包类似 Gnus 的初始化文件。您可以在文件的第一行中的注释里写 '-*-unibyte: t;-*-',指定以单字节方式加载(参见文件变量)。这样文件总是以单字节文本加载,即使没有使用 '--unibyte' 启动 Emacs 也是如此。这样约定的初衷是以同样方式加载所有 Lisp 文件比较可靠。但是,您可以在任何时候,用 C-x <RET> c raw-text <RET> 以单字节方式加载一个 Lisp 文件。
|
||||
|
||||
状态行指示了当前缓冲区是否启用了多字节支持。如果是的话,在最前的冒号前面会有两个或多个字符(通常是两个连接线)。如果没有启用多字节字符,冒号前只会有一个连接线。
|
||||
|
||||
语言环境
|
||||
|
||||
启用了多字节字符支持的 Emacs 缓冲区可以支持所有 Emacs 支持的字符集;不必设置特定语言也可以在 Emacs 缓冲区中显示它的文字。但是,选择 语言环境 的重要性在于,这样设置了很多默认值。语言环境实际是对文字的选择,而不是语言的选择。
|
||||
|
||||
语言环境控制了读取文本时使用的编码系统(参见指定编码)。它对文件、接收邮件、新闻和其他读入 Emacs 的文本都有效。它可能还设定了新建文件时的默认编码系统。每种语言环境还设定了默认的输入法。
|
||||
|
||||
要选择一种语言环境,可以设置变量 current-language-environment 或使用命令 M-x set-language-environment。运行命令时所在的缓冲区并不重要,因为设置是在整个 Emacs 会话中全局有效的。所支持的语言环境包括ï¼
|
||||
Belarusian, Brazilian Portuguese, Bulgarian, Chinese-BIG5, Chinese-CNS, Chinese-EUC-TW, Chinese-GB, Croatian, Cyrillic-ALT, Cyrillic-ISO, Cyrillic-KOI8, Czech, Devanagari, Dutch, English, Ethiopic, French, Georgian, German, Greek, Hebrew, IPA, Italian, Japanese, Kannada, Korean, Lao, Latin-1, Latin-2, Latin-3, Latin-4, Latin-5, Latin-6, Latin-7, Latin-8 (Celtic), Latin-9 (updated Latin-1 with the Euro sign), Latvian, Lithuanian, Malayalam, Polish, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Tajik, Tamil, Thai, Tibetan, Turkish, UTF-8 (for a setup which prefers Unicode characters and files encoded in UTF-8), Ukrainian, Vietnamese, Welsh, and Windows-1255 (for a setup which prefers Cyrillic characters and files encoded in Windows-1255).
|
||||
要在图形显示器上显示您的语言环境使用的文字,需要有合适的字体。如果一些字符显示为中空的方块,您应当安装 GNU Intlfonts 软件包,它包含了大多数文字的字体6。参见字体集中有关设置字体的细节。
|
||||
|
||||
一些操作系统允许你设置字符集,通过设置环境变量 LC_ALL, LC_CTYPE 或 LANG7。在启动 Emacs 的时候,Emacs 在系统语言环境别名表中查找您的字符集名称,与变量 locale-charset-language-names 和 locale-language-names 的值中的条目对比,如果找到匹配就选择相应的语言环境。(前者优先级比后者高。)它随即调整显示和终端编码系统,语言环境编码系统,语言环境的首选编码系统,以及 Emacs 解码键盘输入的非 ASCII 字符的方式。
|
||||
|
||||
如果您在运行 Emacs 时修改了 LC_ALL, LC_CTYPE 或 LANG 环境变量,您可以运行 set-locale-environment 命令来根据新的语言环境重新调整。
|
||||
|
||||
命令 set-locale-environment 通常使用语言环境首选的编码系统来解码系统消息。但是如果您的 locale 匹配变量 locale-prefered-coding-systems 中的条目,Emacs 将使用相应的编码系统代替。例如,如果 locale 'ja_JP.PCK' 匹配 locale-prefered-coding-systems 中的 japanese-shift-jis,Emacs 会使用这个编码,即使通常会首选 japanese-iso-8bit。
|
||||
|
||||
您可以覆盖启动时选择的语言环境,只要显式调用 set-language-environment,或在初始化文件中定制 current-language-environment。
|
||||
|
||||
要显示特定语言环境 lang-env 的效果,运行命令 C-h L lang-env <RET>(describe-language-environment)。它会告诉您语言环境适用的语言,字符集,编码系统,以及可以用的输入法。它还会显示示例文本来描述语言环境使用的文字。默认情况下,它显示当前语言环境的信息。
|
||||
|
||||
您可以定制任意语言环境,使用 HOOK set-language-environment-hook。命令 set-language-environment 在设置语言环境后运行这个 HOOK。HOOK 函数通过检测变量 current-language-environment 来发现特定的语言环境。可以在 HOOK 中为某个语言环境设置非默认的内容,例如键盘输入和终端输出的编码系统,默认的输入法等等。
|
||||
|
||||
在设置语言环境之前,set-language-environment 首先运行 HOOK exit-language-environment-hook。这个 HOOK 对于撤销在 set-language-environment-hook 中做出的定制很有用。例如,如果您在 set-hook 中对某个语言环境的按键关联做了设置,应当设置 exit-language-environment-hook 恢复按键的默认设置。
|
||||
|
||||
输入法
|
||||
|
||||
输入法 是一种字符转换,为交互输入而特别设计。在 Emacs 中,通常每种语言都有自己的输入法;有时使用相同字符的多种语言可以共用一种输入法。一些语言支持多种输入法。
|
||||
|
||||
最简单的输入法,是将 ASCII 字母映射到另一个字母表;这样就可以使用另一种字母表了。希腊文和俄文输入法是这样做的。
|
||||
|
||||
更强大的办法是组合:将字符序列转换为一个字母。很多欧洲文字输入法使用组合来产生单个非 ASCII 字母,通过输入由字母和音调标记组成的序列(或反过来)。例如,一些输入法将序列 a' 转换为单个注音字符。这些输入法没有自己特殊的命令;它们只是组合可打印字符的序列。
|
||||
|
||||
拼音文字的输入法通常在组合之后进行映射。泰文和朝鲜文是这样的。首先,字母被映射到特殊音节或音调的符号;然后,符号的序列构成了整个音节,被映射为一个拼音文字。
|
||||
|
||||
中文和日文需要更复杂的输入法。在中文输入法中,首先输入的是汉字的拼音(在 chinese-py 输入法中),或者字符的部件代码序列(在 chinese-4corner 和 chinese-sw 输入法中)。一种输入序列通常对应多种可能的中文字符。这时,可以用按键 C-f, C-b, C-n, C-p 以及数字来选择它们,这些按键有着特殊的意义。
|
||||
|
||||
可能的字符被排成几行,每行包含不超过 10 个候选字。通常,Emacs 一次只在回显区显示一行;以 (i/j) 开始来指示是总计 j 行中的第 i 行。输入 C-n 或 </code>C-p</code> 来显示下一行或上一行。
|
||||
|
||||
输入 C-f 和 C-b 来在当前行的候选字中前后移动。这样做的时候,Emacs 会用特殊颜色标示当前选择;输入 C-<SPC> 来接受当前选择作为输入。一行中的待选字都有编号,显示在每个字前面。输入数字 n 就可以选择当前行的第 n 个待选字,作为输入。
|
||||
|
||||
在中文输入法中按下 <TAB> 会显示一个包含所有可能字符的缓冲区;然后在字符上单击 Mouse-2 就可以选择候选字。按键 C-f, C-b, C-n, C-p 和数字同样可用,只是它们会在缓冲区中高亮标示当前的字符,而不是在回显区。
|
||||
|
||||
在日文输入法中,首先使用拼音输入整个词;然后,当词输入缓冲区后,Emacs 将它转换为一个或多个字符,根据一个大辞典。每个拼音对应多个不同的日文词;使用 C-n 和 C-p 来在待选字中循环选择。
|
||||
|
||||
有时需要禁止输入法处理,使您输入的字符不会与后续字符结合。例如,在输入法 latin-1-postfix 中,序列 e' 结合构成带音调的 'e'。但是怎么把它们输入成单独的字符呢?
|
||||
|
||||
一种方法是输入两次音调;这是输入单独的字符和音调的特殊方法。例如,e'' 将得到两个字符 ‘e'’。另一种办法是在 e 后面输入一个不会与它结合的字母,然后立即删掉它。例如,输入 ee<DEL>' 来得到单独的 e 和 ‘'’。
|
||||
|
||||
还有一种办法,更加通用但是不太容易输入,是在两个字符间按下 C-\ C-\,禁止它们结合。也就是使用命令 C-\(toggle-input-method) 两次。
|
||||
|
||||
在增量搜索中,C-\ C-\ 尤其有用,因为它停止等待结合多个字符,开始搜索您已输入的内容。
|
||||
|
||||
要查询如何在当前输入法中输入光标下的字符,用 C-u C-x =。参见位置信息</a>。
|
||||
|
||||
变量 input-method-highlight-flag 和 input-method-verbose-flag 控制了输入法如何判断当前状态。如果 input-method-highlight-flag 不是 nil,部分输入的序列将在缓冲区中高亮显示(大部分输入法如此,一些输入法禁止了这个特性)。如果 input-method-verbose-flag 不是 nil,联想的字符列表将显示在回显区(不过在辅助缓冲区中输入时不会如此)。
|
||||
|
||||
选择输入法
|
||||
|
||||
C-\
|
||||
打开或关闭所选的输入法
|
||||
C-x <RET> C-\ method <RET>
|
||||
为当前缓冲区选择新输入法
|
||||
C-h I method <RET>
|
||||
C-h C-\ method <RET>
|
||||
描述输入法 method(describe-input-method)。默认情况下,它描述当前的输入法,如果有的话。描述中包含了如何使用输入法的详细信息
|
||||
M-x list-input-methods
|
||||
列出支持的输入法
|
||||
|
||||
要为当前缓冲区选择输入法,输入 C-x <RET> C-\(set-input-method)。命令从辅助缓冲区读取输入法名称,名称通常以输入法所属的语言环境开始。变量 current-input-method 记录了所选的输入法。
|
||||
|
||||
输入法使用 ASCII 字符序列来表示非 ASCII 字符。有时,需要临时关闭输入法,可以输入 C-\(toggle-input-method)。要重新打开输入法,再输入一次 C-\。
|
||||
|
||||
如果您输入了 C-\ 却尚未选择一种输入法,它将提示您指定一个。这与 C-x <RET> C-\ 指定输入法的效果是一样的。
|
||||
|
||||
当带有数字参数执行时,例如 C-u C-\,toggle-input-method 总是提示您指定输入法,并且会把最近使用的输入法作为建议的默认值。
|
||||
|
||||
选择语言环境会为各种缓冲区设定默认的输入法。当设定了默认的输入法之后,要在当前缓冲区中使用它,请输入 C-\。变量 default-input-method 保存了默认的输入法,如果没有就是 nil。
|
||||
|
||||
在一些语言环境中支持多种输入法,set-language-environment 中设定的默认输入法可能并不合您的心意。您可以让 Emacs 在特定语言环境中,设定另一种输入法为默认值,只要用命令 set-language-environment-hook (参见语言环境)。例如,
|
||||
|
||||
(defun my-chinese-setup ()
|
||||
"Set up my private Chinese environment."
|
||||
(if (equal current-language-environment "Chinese-GB")
|
||||
(setq default-input-method "chinese-tonepy")))
|
||||
(add-hook 'set-language-environment-hook 'my-chinese-setup)
|
||||
这样会设置默认输入法为 chinese-tonepy,在您选择 Chinese-GB 语言环境的时候。
|
||||
|
||||
一些字母文字的输入法本质上是将键盘重新映射,以模拟这些文字中常用的键盘布局。正确地重映射依赖于您的实际键盘布局。要指定您的键盘布局,使用命令 M-x quail-set-keyboard-layout。
|
||||
|
||||
您可以用命令 M-x quail-show-key 来显示在当前所选键盘布局中,为输入光标下的字符,应当按什么键(或按键序列)。命令 C-u C-x = 也在显示字符其他信息的同时,显示这一信息。
|
||||
|
||||
要显示所有支持的输入法,输入 M-x list-input-methods。列表中会给出各种输入法的信息,包括状态行中代表它的字符。
|
||||
|
||||
多字节转换
|
||||
|
||||
当启用多字节字符时,从八进制 0240 到 0377 的字符是不能出现在缓冲区中的。有效的非 ASCII 可打印字符的编码从 0400 开始。
|
||||
|
||||
如果您输入了一个 0240 到 0377 之间的字符,或者用 C-q 输入了它,Emacs 假设您要使用的是 ISO Latin-n 字符集之一,然后将它转换为代表这个 Latin-n 字符的 Emacs 代码。您应通过语言环境设置要使用的 ISO Latin 字符集,如果不指定,默认就是 Latin-1。
|
||||
|
||||
如果您输入了一个 0200 到 0237 之间的字符,也就是在 eight-bit-control 集合中的字符,它将被不变地插入。您不应这样做,因为这样缓冲区必须保存为 emacs-mule 或 raw-text 编码系统,这大概不是您想得到的。
|
||||
|
||||
编码系统
|
||||
|
||||
不同语言的用户建立了很多"标准"的编码系统来表示语言。Emacs 内部不使用这些编码系统;它在读取数据时从各种编码系统转换到自己的系统,在写数据时又将内部编码系统转换成其他编码系统。转换发生在读写文件,读写终端,以及与子进程交换数据的时候。
|
||||
|
||||
Emacs 为每个编码系统取一个名字。大多数编码系统只针对一种语言,编码系统的命名以语言名称开始。一些编码系统用于多种语言;它们的名字通常以 'iso' 开始。还有一些特殊的编码系统,包括 no-conversion,raw-text 和 emacs-mule,不对可打印字符做任何转换。
|
||||
|
||||
编码系统中,有特殊的一类,统称为代码页(codepage),用在 MS-Windows 和 MS-DOS 中编码文本。这些代码系统的命名是 cpnnnn,这里 nnnn 是 3 位或 4 位的代码页编号。您可以像其他代码页一样使用它;例如,要打开以代码页 850 编码的文件,输入 C-x <RET> c cp850 <RET> C-x C-f filename <RET>。
|
||||
|
||||
除了转换非 ASCII 字符的不同表示之外,编码系统还进行换行符的转换。Emacs 处理三种文件中换行的方式:新行符,回车换行,或者仅仅回车。
|
||||
|
||||
C-h C coding <RET>
|
||||
描述编码系统 coding
|
||||
C-h C <RET>
|
||||
描述当前使用的编码系统
|
||||
M-x list-coding-systems
|
||||
显示所有支持的编码系统的列表
|
||||
|
||||
命令 C-h C(describe-coding-system) 显示特定编码系统的信息。您可以指定编码系统名称作为参数;或者,不指定参数,它将描述当前使用的各种编码系统,包括当前缓冲区、默认值,以及识别编码系统的优先级列表(参见识别编码)。
|
||||
|
||||
要显示所有支持的编码系统,输入 list-coding-systems。列表中包含了各种编码系统的信息,包括用在状态行中的代表字母(参见状态行)。
|
||||
|
||||
列表中出现的编码系统,除了不作任何转换的 no-conversion 外,都指定了如何转换可打印字符的办法,而换行符转换取决于每个文件的内容。例如,如果文件内容用了回车换行序列区分各行,那么将进行 DOS 换行符转换。
|
||||
|
||||
列表中每种编码系统都包括三种变种,确切指定了换行符转换的方式:
|
||||
|
||||
...-unix
|
||||
不作转换;假设文件使用新行符来分行。(这是 Unix 和 GNU 系统中的方式)
|
||||
...-dos
|
||||
假设文件使用回车换行来分行,做相应转换。(这是 Microsoft 系统中的方式9)
|
||||
...-mac
|
||||
假设文件使用回车来分行,做相应转换。(这是 Macintosh 系统中的方式)
|
||||
|
||||
为求简洁,在 list-coding-systems 的输出中忽略这些变种,因为它们可以构造出来。例如,iso-latin-1 编码系统的变种就是 iso-latin-1-unix,iso-latin-1-dos 和 iso-latin-1-mac。
|
||||
|
||||
编码系统 raw-text 用来处理大部分是 ASCII,但是包含大于 127 的字节值,而它们不是非 ASCII 字符的情况。在 raw-text 编码系统中,Emacs 将不变地复制这些字节值,并且设置当前缓冲区的 enable-multibyte-characters 为 nil,以正确解析它们。raw-text 以通常方式处理换行符,也就是基于文件内容判断,也有三种变种来指定转换的方式。
|
||||
|
||||
与之对比,编码系统 no-conversion 不作任何字符代码转换,无论是非 ASCII 字节值还是换行符。这在读写二进制文件、tar 归档文件和其他必须不变地处理的文件时游泳。它也将 enable-multibyte-characters 设置为 nil。
|
||||
|
||||
最简单的编辑文件而不作任何转换的办法是用 M-x find-file-literally 命令。它启用 no-conversion,并且禁止其他可能在您看到文件内容前作转换的 Emacs 特性。参见查看。
|
||||
|
||||
编码系统 emacs-mule 意味着文件包含非 ASCII 字符,以 Emacs 内部编码保存。它基于文件内容判断换行符,也有三种变种来指定转换的方式。
|
||||
|
||||
识别编码
|
||||
|
||||
Emacs 尝试识别给定文本的编码,这是读取文本时重要的一步。(无论是读取文件、子进程的输出,还是 X 选区都是如此。) Emacs 大多数时候都可以选出正确的编码系统,只要您指定了优先级。
|
||||
|
||||
一些编码系统可以通过数据中的字节序列来识别或区分。但是,有些编码系统无法区分,毫无办法。例如,无法区分 Latin-1 和 Latin-2;它们使用相同的字节,代表了不同的含义。
|
||||
|
||||
Emacs 用编码系统优先级列表处理这种情况。当 Emacs 读取文件时,如果您不指定要使用的编码系统,Emacs 就针对每种编码系统检测数据,从优先级最高的开始,直到找到与数据匹配的编码系统为止。然后,它转换文件内容,假定文件是以这种编码系统表示。
|
||||
|
||||
编码系统的优先级列表依赖于所选的语言环境(参见语言环境)。例如,如果您说法语,您会希望 Emacs 首选 Latin-1 而不是 Latin-2;如果您说捷克语,您可能更希望 Latin-2 是首选。这也是指定语言环境的原因之一。
|
||||
|
||||
您可以用 M-x prefer-coding-system 来调整编码系统的优先级列表。这个命令从辅助缓冲区中读取编码系统的名称,然后将它插入到优先级列表的最前,这样它就成了首选。如果您多次执行这个命令,每次都将向优先级列表最前插入一个元素。
|
||||
|
||||
如果您使用指定了带换行符转换的编码系统,类似 iso-8859-1-dos,Emacs 将首先尝试识别 iso-8859-1,如果识别到,就使用 DOS 换行转换。
|
||||
|
||||
有时文件名指定了要使用的编码系统。变量 file-coding-system-alist 保存了这种对应关系。有一个特别的函数 modify-coding-system-alist,用来向列表加入元素。例如,要用编码系统 chinese-iso-8bit 读写所有 '.txt' 文件,可以执行 Lisp 表达式
|
||||
(modify-coding-system-alist 'file "\\.txt\\'" 'chinese-iso-8bit)
|
||||
第一个参数是 file,第二个参数是一个正则表达式,指定了要应用的文件,第三个参数是要在这些文件中使用的编码系统。
|
||||
|
||||
Emacs 根据文件内容判断使用哪种换行符转换:如果它只读到了回车,或者只读到了回车换行序列,那么它将随之选择转换。您可以禁掉自动的转换,只要设置变量 inhibit-eol-conversion 为非 nil。如果这样,DOS 文件在缓冲区中将显示为包含 '^M' 字符;有些人认为这样比在状态行左侧显示小小的 '(DOS)' 标记更好(参见换行助记符)。
|
||||
|
||||
默认情况下,自动探测对于转义序列是敏感的。如果 Emacs 发现以转义字符开始的转义序列,并且序列可以识别为 ISO-2022 代码,那么 Emacs 将使用 ISO-2022 编码之一来解码文件。
|
||||
|
||||
但是,如果您希望转义序列被原样读出,这时就应当设置变量 inhibit-iso-escape-detection 为非 nil。这样,编码检测将忽略转义序列,不使用 ISO-2022 编码。结果是,转义序列将在缓冲区中可见。
|
||||
|
||||
inhibit-iso-escape-detection 的默认值是 nil。我们建议您不要一直改变它的值,只在特定的操作中改变它。这是因为很多 Emacs Lisp 源代码包含非 ASCII 字符,以 iso-2022-7bit 编码系统编码,如果禁止转义序列探测,将无法正确读取解码这些文件。
|
||||
|
||||
您可以在某个文件的开始,用 '-*-...-*-' 结构来指定编码系统,或者在文件结尾用局部变量列表指定(参见文件变量)。看起来像是指定了"变量" coding 的值,实际上 Emacs 并没有叫做 coding 的变量;它只是用指定的编码系统作为文件的编码。例如,‘-*-mode: C; coding: latin-1;-*-’ 指定使用 Latin-1 编码系统和 C 模式。当您在文件中指定编码后,它将覆盖 file-coding-system-alist 的值。
|
||||
|
||||
变量 auto-coding-alist,auto-coding-regexp-alist 和 auto-coding-functions 是为特定文件名模式,或包含特定模式的文件,指定编码系统的最有力的手段;它们甚至比文件中指定的 '-*-coding:-*-' 标记优先级更高。Emacs 使用 auto-coding-alist 来处理 tar 和存档文件,避免存档文件中,某个文件的 '-*-coding:-*-' 标记导致整个存档文件被一起处理。同样,Emacs 使用 auto-coding-regexp-alist 来保证文件名毫无规律的 RMAIL 文件可以被正确解码。某个内建的 auto-coding- 函数可以检测 XML 文件的编码。
|
||||
|
||||
如果 Emacs 没有正确识别文件的编码,您可以用 C-x <RET> r coding-system <RET> 来用正确的编码系统重新读取文件。要查看 Emacs 实际用来解码文件的编码系统,查看状态行左侧的编码系统助记符(参见状态行)或者输入 C-h C <RET>。
|
||||
|
||||
当解码文本时,命令 unify-8859-on-decoding-mode 启用一种"归一化"拉丁字母表的模式。具体办法是将非 ASCII 的 Latin-n 字符转换为 Latin-1 或 Unicode 字符。这样就可以简单地同时使用多种 Latin-n 字母表了。在将来版本的 Emacs 中,我们希望可以全面转向 Unicode,实现完整的字符集统一。
|
||||
|
||||
当 Emacs 为一个缓冲区选定编码系统后,它将编码系统保存在 buffer-file-coding-system 中,默认情况下,在将缓冲区写入文件时使用这个编码系统。保存操作包括 save-buffer 和 write-region。如果您希望以不同的编码系统来保存缓冲区到文件,可以用 set-buffer-file-coding-system 为缓冲区设置不同的编码系统(参见指定编码)。
|
||||
|
||||
您可以向任意 Emacs 缓冲区插入任意字符,但是大多数编码系统只能处理有限的字符。这意味着,插入的字符可能无法用保存时使用的编码系统编码。例如,您可以打开一个 ASCII 文件,插入一些 Latin-1 字符,或者打开 iso-8859-2 编码的波兰文字并插入一些俄语词汇。当保存缓冲区的时候,Emacs 就无法使用 buffer-file-coding-system 的当前值,因为您插入的字符无法以那种编码系统编码。
|
||||
|
||||
出现这种情况时,Emacs 将尝试优先级最高的编码系统(由 M-x prefer-coding-system 或 M-x set-language-environment 设置),如果这些编码系统可以安全地编码缓冲区中所有字符,Emacs 就会用它保存,并将它的值保存在 buffer-file-coding-system 中。否则,Emacs 将显示一系列可用于编码缓冲区内容的编码系统,让您选择用哪一个。
|
||||
|
||||
如果您向邮件消息中插入不合适的字符,Emacs 的行为会稍有区别。它将检测优先级最高的编码系统是否可以用于 MIME 消息。如果不能,Emacs 将提示优先级最高的编码系统并不合适,并提示选择另外一个。这样,您就不会无意间发出接受方无法解码的消息。(如果您确实希望用优先级最高的那个编码系统,只要在提示时仍然选择它。)
|
||||
|
||||
当在 Mail 邮件模式下发送消息时(参见发送邮件),Emacs 有四种方法来判断用于编码消息文本的编码系统。它尝试缓冲区本身的 buffer-file-coding-system 值,如果非 nil 的话。否则,它将尝试 sendmail-coding-system 的值,如果非空的话。第三种办法是使用新文件的默认编码系统,如果非空的话,它由您的语言环境决定。如果前面三个变量都是 nil,Emacs 将用 Latin-1 编码系统来编码发出的邮件。
|
||||
|
||||
当您在 RMAIL 中收到新邮件时,每条消息都自动以自己的编码系统来解码,就好像单独的文件一样。解码会使用您指定的编码系统优先级列表。如果 MIME 消息指定了字符集,RMAIL 将遵照约定,除非 rmail-decode-mime-charset 是 nil。
|
||||
|
||||
对于读取和保存 RMAIL 文件本身,Emacs 使用 rmail-file-coding-system 指定的编码系统。默认值是 nil,也就是说 RMAIL 文件不会转换(它们将使用 Emacs 内部字符表示来读写)。
|
||||
|
||||
指定编码
|
||||
|
||||
当 Emacs 无法自动选择正确的编码系统时,您可以用这些命令来指定一个:
|
||||
C-x <RET> f coding <RET>
|
||||
使用编码系统 coding 来查看当前缓冲区中的文件。
|
||||
C-x <RET> c coding <RET>
|
||||
指定下一个命令的编码系统为 coding。
|
||||
C-x <RET> k coding <RET>
|
||||
设置键盘输入的编码系统为 coding。
|
||||
C-x <RET> t coding <RET>
|
||||
设置终端输出的编码系统为 coding。
|
||||
C-x <RET> p input-coding <RET> output-coding <RET>
|
||||
使用编码系统 input-coding 和 output-coding 作为当前缓冲区中子进程的输入和输出。
|
||||
C-x <RET> x coding <RET>
|
||||
在窗口系统中与其它程序传递选中文本时使用编码系统 coding。
|
||||
C-x <RET> X coding <RET>
|
||||
在窗口系统中与其它程序传递下一次选中文本时(仅一次)使用编码系统 coding。
|
||||
|
||||
命令 C-x <RET> f(set-buffer-file-coding-system) 指定当前缓冲区的文件的编码系统。换句话说,在保存或重读取当前文件时使用的编码系统。您在辅助缓冲区中指定要使用的编码系统。由于这个命令只对您已打开的文件有用,它只影响文件保存的方式。
|
||||
|
||||
还有一种指定编码系统的办法是在打开文件的时候。首先用命令 C-x <RET> c(universal-coding-system-argument);这个命令在辅助缓冲区中提示输入编码系统的名称。之后,这个编码系统会作用于 紧随其后的命令。
|
||||
|
||||
因此,如果紧随其后的命令是 C-x C-f,那么它将使用指定的编码系统来打开文件 (也会在后面保存文件时使用这个编码系统)。如果紧随其后的命令是 C-x C-w,它将用这个编码系统写文件。如果这样指定保存文件的编码,与 C-x <RET> f 命令不同,当缓冲区包含编码系统无法处理的字符时不再警告。
|
||||
|
||||
其他受指定编码系统影响的命令包括 C-x C-i 和 C-x C-v,以及在其他窗口中打开文件的 C-x C-f 变体。C-x <RET> c 影响产生子进程的命令,包括 M-x shell (参见 Shell 交互环境)。
|
||||
|
||||
如果紧随其后的命令不使用编码系统,那么 C-x <RET> c 没有任何作用。
|
||||
|
||||
要在查看文件时不作转换,可以用命令 M-x find-file-literally。参见查看。
|
||||
|
||||
变量 default-buffer-file-coding-system 指定了创建新文件时的编码系统。当打开新文件、创建缓冲区并保存为文件的时候将应用它。设置语言环境通常会设置这个变量为合适的默认值。
|
||||
|
||||
如果您使用错误的编码系统查看文件,您可以用 C-x <RET> r(revert-buffer-with-coding-system) 来纠正。这个命令用您指定的编码重新查看文件。
|
||||
|
||||
命令 C-x <RET> t(set-terminal-coding-system) 指定终端输出的编码。如果您指定了终端输出的编码,所有输出到终端的字符将转换为那个编码。
|
||||
|
||||
这个特性用于内建特定语言或字符集支持的字符终端,例如,欧式终端,支持 ISO Latin 字符集之一。您在使用多字节文本时需要指定终端编码系统,这样 Emacs 就可以知道终端实际支持的字符。
|
||||
|
||||
默认情况下,到终端的输出不会做任何转换,除非 Emacs 可以根据终端类型或您的语言环境设定推断出使用的编码 (参见 语言环境)。
|
||||
|
||||
命令 C-x <RET> k(set-keyboard-coding-system) 或者变体 keyboard-coding-system 指定了键盘输入的编码。键盘输入的字符代码转换对于带有不可打印的 ASCII 字符按键的终端很有用,例如一些为 ISO Latin-1 字符集或其子集设计的终端。
|
||||
|
||||
默认情况下,键盘输入是根据系统语言环境设置来转换的。如果终端不支持语言环境设定的编码 (例如,输入 M-i 得到了非 ASCII 字符),您需要设置 keyboard-coding-system 为 nil 来关闭编码。您可以将这一句
|
||||
(set-keyboard-coding-system nil)
|
||||
写入您的 ~/.emacs 文件。
|
||||
|
||||
对键盘输入转换编码系统,与使用一种输入法,其间有相似之处:它们都定义了键盘输入的序列,转换为单个字符。但是,输入法是为了让人可以方便地交互使用的,要转换的序列通常是 ASCII 字符串。编码系统通常转换的是不可打印的字符。
|
||||
|
||||
命令 C-x <RET> x(set-selection-coding-system) 指定了向窗口系统发送所选文本,以及接受从其他应用程序中选取的文本时的编码系统。命令对全部后续选取都会有效,除非您再次用它指定了别的编码。命令 C-x <RET> X(set-next-selection-coding-system) 指定了下一次 Emacs 读取或选中文本时的编码系统。
|
||||
|
||||
命令 C-x <RET> p(set-buffer-process-coding-system) 指定了向子进程输入输出时的编码系统。这个命令对当前缓存有效,每个子进程都有自己的缓存,因此您可以在一个子进程的缓存中执行这个命令,以为这个子进程指定输入和输出的转换。
|
||||
|
||||
进程输入输出转换的默认值依赖于当前语言环境。
|
||||
|
||||
如果文本插入缓冲时使用了错误的编码系统,您可以用 M-x recode-region 再次解码。它将提示您输入旧的编码系统以及期望的编码系统,然后转换选区中的文本。
|
||||
|
||||
变量 file-name-coding-system 指定了编码文件名时的编码系统。如果您将它设置为一个编码系统的名称 (一个 Lisp 符号或字符串),Emacs 将在所有文件操作中使用此编码系统来编码文件名。这样就可以在文件名中使用非 ASCII 字符了,或者说,可以用指定编码系统中包含的非 ASCII 字符。使用 C-x <RET> F(set-file-name-coding-system) 来交互地指定它。
|
||||
|
||||
如果 file-name-coding-system 是 nil,Emacs 将使用默认的编码系统,由语言环境决定。在默认语言环境中,文件名中的非 ASCII 字符不会被特别编码;它们以 Emacs 内部表示出现在文件系统中。
|
||||
|
||||
警告: 如果您在一次 Emacs 会话当中修改了 file-name-coding-system (或语言环境),如果打开的文件使用先前的编码系统来编码文件名,但是文件名无法在新的编码系统中正确编码 (或编码有所不同),就会出问题。如果您试图用原来的文件名保存缓冲区,保存结果可能是错误的名字,或者会产生错误。如果出现这种问题,用 C-x C-w 为那个缓冲区设置一个新的文件名。
|
||||
|
||||
如果编码文件名时出错,使用命令 M-x recode-file-name 来改变文件名的编码系统。它将提示已有的文件名,旧的编码系统,以及要转换到的编码系统。
|
||||
|
||||
变量 locale-coding-system 指定编码和解码系统字符串,类似系统错误消息和 format-time-string 格式以及时间戳时的编码系统。它也用来解码 X 窗口系统中的非 ASCII 键盘输入。您应当选择一个与底层文本表示相兼容的编码系统,通常它是由环境变量 LC_ALL,LC_CTYPE 和 LANG 之一决定的 (这三个变量,按照这个顺序,第一个非空的值将决定文本表示的编码)。
|
||||
|
||||
字体集
|
||||
|
||||
每种 X 字体通常只定义一种字母表或文字的字形。因此,要显示 Emacs 支持的所有文字,需要很多字体才行。在 Emacs 中,这样的字体集合被称为字体集 fontset。字体集是以一系列字体定义的,每种字体负责一批字符。
|
||||
|
||||
每个字体集有一个名字,就像字体一样。可用的 X 字体是由 X 服务器定义的,而字体集是 Emacs 自行定义的。当您定义了一个字体集后,就可以在 Emacs 中引用它的名字,把它用在任何可以使用单个字体的地方。当然,Emacs 字体集只能包含 X 服务器支持的字体;如果某些字符在屏幕上显示为中空的方块,这表示在当前使用的字体集中不包含对应这些字符的字体。7
|
||||
|
||||
Emacs 自动创建两个字体集:标准 (standard) 和启动 (startup) 字体集。标准字体集可能包含针对宽泛的非 ASCII 字符的字体;但是,这不是 Emacs 默认使用的字体。(默认情况下,Emacs 尝试使用有粗体和斜体变体的字体。)您可以用 -fn 命令行选项,或 Font 资源(参见 X 字体(Font X))。例如,
|
||||
emacs -fn fontset-standard
|
||||
|
||||
字体集不会为每个字符编码都设定字体。如果一个字体集没有为某个字符设定字体,或者设定了您的系统中不存在的字体,那么它将无法正确显示这个字符。这个字符将被显示为一个中空的方块。
|
||||
|
||||
字体集的高度和宽度是由 ASCII 字符决定的(也就是,字体集中用于显示 ASCII 字符的字体)。如果字体集中另一个字体拥有不同的高度或不同的宽度,那么用这些字体显示的字符将被截断为字体集的大小。如果 highlight-wrong-size-font 不为 nil,还将在大小错误的字符周围显示一个方框。
|
||||
|
||||
定义字体集
|
||||
|
||||
Emacs 根据 standard-fontset-spec 的值,自动创建标准字体集。字体集的名字是
|
||||
-*-fixed-medium-r-normal-*-16-*-*-*-*-*-fontset-standard
|
||||
也可以使用简称 fontset-standard。
|
||||
|
||||
标准字体集的粗体、斜体和粗斜体变种都是自动创建的。它们的名字是以 bold 替换 medium,以 i 替换 r,或者同时替换二者得到的。
|
||||
|
||||
如果您使用 Font 资源(X 窗口系统),或者 -fn 命令行参数设定默认 ASCII 字体,Emacs 将自动为它创建一个字体集,也就是启动字体集,它的名字是 fontset-startup。创建步骤是将厂商、字体族、附加属性和平均宽度域替换为星号,将字符集登记(charset_registry,[mhss])替换为 fontset,将字符集编码替换为 startup,然后用结果字符串指定字体集。
|
||||
|
||||
例如,如果您这样启动 Emacs,
|
||||
emacs -fn "*courier-medium-r-normal--14-140-*-iso8859-1"
|
||||
Emacs 将生成下面的字体集,用在最初的 X 窗口窗格中:
|
||||
-*-*-medium-r-normal-*-14-140-*-*-*-*-fontset-startup
|
||||
|
||||
在 X 资源 emacs.Font 中,您可以指定字体集名称,像真实字体名一样用它。但是小心不要在通配符表达的资源中(类似 emacs*Font)指定字体集名称--通配符可以匹配各种其他资源,包括菜单等等,而菜单无法处理字体集。
|
||||
|
||||
您可以在名为 Fontset-n 的 X 资源中指定附加的字体集,这里 n 是一个整数,从 0 开始。资源值应该是下面的形式:
|
||||
fontpattern, [charsetname:fontname]...
|
||||
fontpattern 应当是标准的 X 字体名,除了最后两个域应当是 fontset-alias 的形式。
|
||||
|
||||
这个字体集有两个名字,其一是长名字,也就是 fontpattern,其二是短名字 fontset-alias。您可以用任何一个名字来引用这个字体集。
|
||||
|
||||
结构 charset:font 指定了对于某个特定的字符集,使用(这个字体集中的)哪个字体。这里,charset 是字符集的名称,而 font 是将在这个字符集中使用的字体。在定义一个字体集的时候,您可以重复这个结构任意次。
|
||||
|
||||
对于其他字符集,Emacs 根据 fontpattern 来选择一种字体。它将 fontset-alias 替换为描述字符集的值。对于 ASCII 字符,fontset-alias 将替换为 ISO8859-1。
|
||||
|
||||
另外,如果有数个连续的域都是通配符,Emacs 将把它们折叠为一个。这是为了避免使用自动缩放的字体。通过缩放大字体得到的字体不适于编辑,而缩放小字体没有用处,因为以原始大小使用小字体效果更好,这就是 Emacs 的做法。
|
||||
|
||||
因此,如果 fontpattern 是这样,
|
||||
-*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24
|
||||
那么 ASCII 字符的字体声明将是:
|
||||
-*-fixed-medium-r-normal-*-24-*-ISO8859-1
|
||||
而中文 GB2312 字符的字体声明将是:
|
||||
-*-fixed-medium-r-normal-*-24-*-gb2312*-*
|
||||
|
||||
您也许没有安装任何匹配上述字体声明的中文字体。大多数 X 发行版仅仅包含 family 域是 song ti 或 fangsong ti 的中文字体。这种情况下,可以把 Fontset-n 声明为:
|
||||
Emacs.Fontset-0: -*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24,\
|
||||
chinese-gb2312:-*-*-medium-r-normal-*-24-*-gb2312*-*
|
||||
这样,所有字体声明,除了中文 GB2312 之外,都在 family 域使用 fixed,而为中文 GB2312 字符使用的字体声明将在 family 域使用星号。
|
||||
|
||||
用来处理字体集资源,创建字体集的函数是 create-fontset-from-fontset-spec。您也可以显式调用它,来创建一个字体集。
|
||||
|
||||
参见 X 字体(Font X) 来获取有关 X 字体命名的更多信息。
|
||||
|
||||
无法显示的字符
|
||||
|
||||
您的终端也许无法显示一些非 ASCII 字符。大多数非窗口系统的终端只能使用单一字符集(设置变量 default-terminal-coding-system (参见指定编码)来告诉 Emacs 用的是哪一个);在这个编码系统中无法编码的字符将默认显示为问号。
|
||||
|
||||
窗口系统的终端可以显示更大范围的字符,但是您也许没有安装完全相应的字体;找不到字体的字符将显示为一个中空的方块。
|
||||
|
||||
如果您用的是 Latin-1 字符集,而终端无法显示 Latin-1,那么您可以设置显示助记的 ASCII 序列。例如,"o 就是变音的 o。加载 iso-ascii 库就可以了。
|
||||
|
||||
如果您的终端可以显示 Latin-1,那么您可以用混合等价的 Latin-1 字符与 ASCII 助记序列的方式,显示其他欧洲字符集的字符。加载 latin1-display 来启用这种行为。助记的 ASCII 序列大都相应于输入法的前缀。
|
||||
|
||||
单字节字符集支持
|
||||
|
||||
ISO 8859 Latin-n 字符集定义了八进制 0240 到 0377(十进制 160 到 255) 范围内的字符代码,来处理各种欧洲语种(以及一些非欧洲语种)中的重音字母以及标点符号。如果您禁用了多字节字符,Emacs 仍然可以处理这些字符集,尽管每次只能处理一种。要设定使用哪一种,执行 M-x set-language-environment 并且指定一个合适的语言环境值,例如 Latin-n。
|
||||
|
||||
要获取更多关于单字节操作的信息,参见使用多字节字符。需要特别注意的是,您也许需要保证初始化文件是以单字节方式读取的,如果其中包含了非 ASCII 字符的话。
|
||||
|
||||
Emacs 可以显示这些字符,只要正在使用的终端或字体支持它们的话,就会自动显示。如果您在使用窗口系统,Emacs 也可以通过字体集来显示单字节字符,它会根据当前语言环境,显示等价的多字节字符。要启用这种效果,可以设置变量 unibyte-display-via-language-environment 为非 nil 值。
|
||||
|
||||
如果终端不支持 Latin-1 字符集,Emacs 可以将这些字符显示为 ASCII 序列,这样至少可以让您知道这些字符是什么。要启用这种效果,加载 iso-ascii 库。针对其他 Latin-n 字符集的库也可以实现,不过我们还没有去做。
|
||||
|
||||
非 ISO 8859 字符(十进制代码 128 到 159,包括两端)将显示为八进制转义符号。对于非标准的"扩展"版本的 ISO 8859 字符集,您可以用 disp-table 库中的 standard-display-8bit 函数来改变这个行为。
|
||||
|
||||
有很多办法,可以用来输入单字节非 ASCII 字符:
|
||||
|
||||
- 如果您的键盘可以产生 128(十进制)及更大的字符编码,表示非 ASCII 字符,那么您可以直接输入那些字符。
|
||||
|
||||
在窗口系统的终端下,您应当无需特别配置就能使用这些键;它们自然而然地就能用。在文本终端下,您应当使用命令 M-x set-keyboard-coding-system 或定制选项 keyboard-coding-system 来指定键盘使用的编码系统(参见指定编码)。启用这一特性很可能需要您使用 Esc 来输入 Meta 字符;但是,在 Linux 终端下或 xterm 中,您可以重新设定 Meta 为输入 Esc,同时仍然可以输入键盘上直接标示的,或用 Compose 或 AltGr 键得到的单字节字符。参见用户输入(User Input)。
|
||||
|
||||
- 您可以使用所选的语言环境中的输入法。参见输入法。当您在单字节的缓冲区中使用输入法时,您在输入法中选择的字符将被转换为单字节。
|
||||
|
||||
- 您可以用按键 C-x 8 作为"组合字符"前缀,输入非 ASCII 的 Latin-1 可打印字符。这只对 Latin-1 有效。C-x 8 在插入(包括命令缓冲区以及其他缓冲区)、搜索和其他任何允许组合键的环境中都可以用。
|
||||
|
||||
C-x 8 需要加载 iso-transl 库。加载之后,<ALT> 修饰键将与 C-x 8 拥有相同的效果;按下 <ALT> 然后按一个重音符号,就可以改变下一个字符。另外,如果您有针对 Latin-1 的重音字符的寂键("dead accent chars"),加载了 iso-transl 之后,它们也被定义为与下一个字符组合。使用 C-x 8 C-h 来列出所有翻译,以及助记的命令名。
|
||||
|
||||
- 对于 Latin-1、Latin-2 和 Latin-3,M-x iso-accents-mode 可以打开一个辅助模式,它与 latin-1-prefix 输入法很像,但是不依赖于输入法。这个模式是缓冲区范围的。用 M-x iso-accents-customize 可以定制它以适于多种语言。
|
||||