Francis's Octopress Blog

A blogging framework for hackers.

Python Hashlib Md5

python hashlib md5

#-*- coding:utf-8 -*- from hashlib import md5 content = 12 content_str = str(content) ciphertext = md5(content_str).hexdigest() #加密 print ciphertext #from hashlib import md5 #ciphertext_str=raw_input() #写入要解密的密文,如827ccb0eea8a706c4c34a16891f84e7b #MD5是不可逆的密码加密,可以说除了暴力破解外无法还原,但同样的输入加密出来的结果是一致的,因此要比较输入是否正确,只要比较一下加密后的结果即可,而Python中可以使用hashlib进行MD5加密,具体方法如下 for i in xrange(100000): ciphertext_tmp = md5(str(i)).hexdigest() if ciphertext_tmp == ciphertext: print ‘the password is %d’ % i break

python的base64加密解密及md5加密

import hashlib a = “a test string” print hashlib.md5(a).hexdigest() print hashlib.sha1(a).hexdigest() print hashlib.sha224(a).hexdigest() print hashlib.sha256(a).hexdigest() print hashlib.sha384(a).hexdigest() print hashlib.sha512(a).hexdigest() import base64 str=’haha’ encoded = base64.b64encode(str) decoded = base64.b64decode(encoded)

 

 

Python Hashlib Module

python hashlib module

#-*- coding:utf-8 -*- from hashlib import md5 content = 12 content_str = str(content) ciphertext = md5(content_str).hexdigest() #加密 print ciphertext  #from hashlib import md5 #ciphertext_str=raw_input() #写入要解密的密文,如827ccb0eea8a706c4c34a16891f84e7b #MD5是不可逆的密码加密,可以说除了暴力破解外无法还原,但同样的输入加密出来的结果是一致的,因此要比较输入是否正确,只要比较一下加密后的结果即可,而Python中可以使用hA

开源许可协议

开源许可协议

1       目的

为了让开发人员能够正确合法的使用开源软件,避免因为不小心而触犯到相关法律法规,产生不必要的法律纠纷,现对开源界的几大开原协议进行了翻译和整理。

2       开源许可协议定义

自由软件/开源软件是自由的,免费的,源代码开放的,我们可自由下载安装和使用。同时,为了维护作者和贡献者的合法权利,保证这些软件不被一些商业机构或个人窃取,影响软件的发展,开源社区开发出了各种的开源许可协议。其中主要分三大类。

OSI-Approved Open Source:被开放源码组织(www.opensource.org)所批准的开放源码授权协议。如常见的Apache,GPL,LGPL,MIT Licence,都属于OSI-Approved的授权协议,OSI 的要求之一是二进制文件和源代码的自由发放。

Other/Proprietary License:其他的,私有的授权协议。指软件作者提供源代码,但是对软件的分发和发布有其他的限制。

Public Domain:公共域授权。将软件授权为公共域,表示作者完全放弃版权,任何人都可以随意使用。

大部分开源工程都属于OSI-Approved Open Source,下面对常见的License做简单的介绍。

3       开源许可协议介绍

3.1              GNU GPL

GNU有两种协议其中一种为 General Public Licence (GPL) ,该协议有可能是开源界最常用的许可模式。GPL 保证了所有开发者的权利,同时为使用者提供了足够的复制,分发,修改的权利。主要条款如下:

  1. 使用者可以将软件自由的复制到任何地方。
  2. 使用者可以以任何方式自由的分发,下载。注意分发的时候需要提供源代码和二进制文件。
  3. 使用者可以盈利,基于 GPL 的软件允许商业化销售,但不允许封闭源代码。
  4. 如果使用者对遵循 GPL 的软件进行任何改动和/或再次开发并予以发布,则使用者的产品必须继承 GPL 协议,不允许封闭源代码。

GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商 业软件公司开发的免费软件了。但对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。GPL3.0详见附录4.1GPL3.0协议

3.2              GNU LGPL

GNU 还有另外一种协议,叫做LGPL(Lesser General Public Licence),它对产品所保留的权利比GPL少,总的来说,LGPL适合那些用于非GPL或非开源产品的开源类库或框架。因为GPL要求,使用了GPL代码的产品必须也使用GPL协议,开发者不允许将GPL代码用于商业产品。而LGPL绕过了这一限制。

  1. 基于LGPL的软件也允许商业化销售,但不允许封闭源代码。
  2. 如果您对遵循LGPL的软件进行任何改动和/或再次开发并予以发布,则您的产品必须继承LGPL协议,不允许封闭源代码。但是如果您的程序对遵循LGPL 的软件进行任何连接、调用而不是包含,则允许封闭源代码。

如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。具体条款详见LGPL 2.1协议

3.3              BSD

BSD授权许可证(FreeBSD Copyright Information)具有多种授权许可证。其中BSD 在软件分发方面的限制比别的开源协议(如GNU GPL)要少。该协议有多种版本,最主要的版本有两个,新BSD协议与简单BSD协议,这两种协议经过修正,都和 GPL 兼容,并为开源组织所认可。简单BSD协议主要条款如下:

  1. 使用者可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。
  2. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  3. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  4. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

新版(也称“三句版”)BSD许可证规定,只要软件的版权申明和许可证的免责条款得以保存,软件可以以任何目的不受限制地分发。该许可证还包含如下条款:即未经许可,不得以软件贡献者的名字为软件的衍生产品做代言。这一条款正是新版BSD许可证与简版BSD许可证之间的主要区别。

3.4              Apache license. 2.0

Apache Licence是著名的非盈利开源组织Apache采用的协议。Apache协议 2.0和别的开源协议相比,除了为用户提供版权许可之外,还有专利许可,对于那些涉及专利内容的开发者而言,该协议最适合。以下为Apache Licence的详细介绍:

  1. 需要授予使用代码的用户一份Apache Licence。一旦被授予许可,使用者可以无限期的使用。
  2. 如果使用者修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

以下是该授权关于对工作中使用的说明和限制:

如果在工作中需要应用该授权,请附上如下样板式说明,以[]围起来,来替换你自己的说明信息。(不要包含括弧)文本通常被适当的文件语法格式所包围。我们也建议,一个文件或者类名和特定目的的描述,一起被包含在印刷页上,该印刷页作为一个简单的第三方文档授权证明。下为授权的文档格式。

 知识共享许可协议 dreamcamp by Francis Jiang is licensed under a Creative Commons 署名-非商业性使用-相同方式共享 3.0 Unported License. 基于github.com上的作品创作。   ## License (The MIT License) Copyright © 2009-2012 Francis Jiang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #### If you want to be awesome. - Proudly display the ‘Powered by Francis Jiang’ credit in the footer. - Add your site to the wiki so we can watch the communi

3.5    MIT许可协议(MIT License)

在所有常用的开源许可协议中,MIT许可协议最为简短,可能也最为广泛。它的条款非常松散,比起大部分其它许可协议来说更加宽松。其基本条款如下:

  1. 使用者可以随意使用,复制,修改这个软件。没有人能够阻止你在任何工程里使用它,你可以复制任意次数、以任何形式,或按你的愿望修改它。
  2. 使用者可以向外免费发放,或出售。你可以随意的分发它,没有任何限制。
  3. 唯一的限制是使用者必须接受协议条款。即软件必须附带版权和许可协议。
  4. MIT 协议是目前最少限制的协议。它基本上就是任何人可以对这个协议下的软件的做任何的事情,只要你能认可这个协议。

3.6    知识共享协议

知识共享(Creative Commons,简称CC)许可协议并非完全的开源许可协议,但设计类项目也常常使用。有各种不同的CC许可协议可供使用,每种授予特定的权利。一个CC许可证包含四个基本部分,每部分即可单独生效,又可联合使用。简述如下:

  1. 署名,使用者必须按照作者指定的方式对作品进行署名。除此之外,作品可被复制、分发、拷贝以及以其它方式使用。
  2. 相同方式共享,即只能基于相同的CC许可证对作品进行修改、分发等。
  3. 非商业性,作品可被修改、分发等,但不得以商业为目的进行。关于什么构成商业行为,许可证条款并未提供清晰的定义,因此使用者可能需要在自己的项目里给予澄清。比如说,有人认为“非商业”只是简单地意味着你不能出售作品,也有人认为你不能把作品放到一个带广告的网站上,还有人认为只有当牟利发生时才能称为“商业”。
  4. 禁止衍生,即使用者可以拷贝和分发授权作品,但不得以任何方式修改、或基于原作进行创作。

如上所述,CC许可证的各个部分可以联合使用。最为严格的许可证为“署名-非商业-禁止衍生”许可证,即使用者可以自由分享作品,但不得修改或收费,同时必须按照作者指定的方式为作品署名。这对那些一方面希望发布作品,另一方面又希望多多少少保留对作品使用方式的控制权的作者来说,颇为不错。限制最少的CC许可证是“署名”许可证,即只要按照作者指定的方式为作品署名,就可以用作品做任何事。

CC许可证在设计类作品中的应用要比在开发中的应用多,但并没有限制你在开发中使用它,只是要清楚各部分条款的细节。

3.7    CPL(Common Public Liecense) vesion 1.0

CPL是IBM 提出的并通过了OSI(Open Source Initiative)批准的开源协议。主要用于一些IBM或跟IBM相关的开源软件 /项目中。如很著名的Java开发环境Eclipse、RIA开发平台Open Laszlo等。

CPL也是一项对商业应用友好的协议。它允许使用者对源码进行任意的使用、复制、分发、传播、展示、修改以及改后做闭源的二次商业发布,这点跟BSD 很类似,也属于自由度比较高的开源协议。但是,需要遵循以下条款:

  1. 当使用者将源码的整体或部分再次开源发布的时候,必须继续遵循CPL 开源协议来发布,而不能改用其他协议发布。除非你得到了原“源码”Owner 的 授权。
  2. CPL协议下,使用者可以将源码不做任何修改来商业发布。但如果要将修改后的源码开源,而且当你再发布的是ObjectCode 的时候,你必须声明它的Source Code是可以获取的,而且要告知获取方法。
  3. 当使用者需要将 CPL 下的源码作为一部分跟其他私有的源码混和着成为一个项目发布的时候,可以将整个项目/产品以私人的协议发布,但要声明哪一部分代码是CPL下的,而且声明那部分代码继续遵循CPL。独立的模块(Separate Module),不需要开源。

3.8              MPL协议

MPL是The Mozilla Public License的简写,是1998年初Netscape的 Mozilla小组为其开源软件项目设计的软件许可证。MPL许可证出现的最重要原因就是,Netscape公司认为GPL许可证没有很好地平衡开发者对源代码的需求和他们利用源代码获得的利益。同著名的GPL许可证和BSD许可证相比,MPL在许多权利与义务的约定方面与它们相同(因为都是符合OSIA认定的开源软件许可证)。但是,相比而言MPL还有以下几个显著的不同之处:

  1. MPL允许免费重发布、免费修改,但要求修改后的代码版权归软件的发起者。这种授权维护了商业软件的利益,它要求基于这种软件得修改无偿贡献版权给该软件。这样,围绕该软件得所有代码得版权都集中在发起开发人得手中。但MPL是无偿使用得。MPL软件对链接没有要求。
  2. MPL要求对于经MPL许可证发布的源代码的修改也要以MPL许可证的方式再许可出来,以保证其他人可以在MPL的条款下共享源代码。但是,在MPL许可证中对“发布”的定义是“以源代码方式发布的文件”,这就意味着MPL允许一个企业在自己已有的源代码库上加一个接口,除了接口程序的源代码以MPL许可证的形式对外许可外,源代码库中的源代码就可以不用MPL许可证的方式强制对外许可。这些,就为借鉴别人的源代码用做自己商业软件开的行为留了一个豁口。
  3. MPL许可证第三条第7款中允许使用者将经过MPL许可证获得的源代码同自己其他类型的代码混合得到自己的软件程序。
  4. 对软件专利的态度,MPL许可证不像GPL许可证那样明确表示反对软件专利,但是却明确要求源代码的提供者不能提供已经受专利保护的源代码(除非他本人是专利权人,并书面向公众免费许可这些源代码),也不能在将这些源代码以开放源代码许可证形式许可后再去申请与这些源代码有关的专利。
  5. MPL许可证第3条有专门的一款是关于对源代码修改进行描述的规定,就是要求所有再发布者都得有一个专门的文件就对源代码程序修改的时间和修改的方式有描述。

3.9              CDDL协议

CDDL全称Common Development and Distribution License.它是一个开源许可证书,采用著名的Mozilla公共许可证(MPL),使其在未做任何改动的情况下可重用。CDDL满足 Open Source Definition 的要求并且已经获得开放源码促进会的认可作为开放源代码的许可证。

  1. MPL作为CDDL的基础。除了保留所有所希望的MPL特性以外(参考前面),CDDL许可证被设计成可重用的,并做了一些改进使其更加通用。
  2. 对于任何遵守CDDL许可的源文件,以及使用者所做的任何修改都需要共享。但是不必将私有源文件共享。
  3. CDDL为在此许可下发布的代码提供了清楚的专利许可。这意味着使用者可以使用、修改并且重新发布CDDL授权的代码而不需要担心代码开发者(包括Sun)的任何技术专利。许可证同时包括了一项条款如果有任何人因为他们所提供的代码而对一个开发者进行专利起诉的话,该条款通过废除代码所有权来阻止任何对于开发者的专利指控。
  4. 可以修改,然后遵守CDDL许可将代码重新发布,并可以进行收费。但是,需要遵循CDDL的条款,包括遵守CDDL许可将修改的代码共享。

4       附录

4.1     GPL3.0协议

4.1.1    导言

GNU通用公共授权是一份针对软件和其他种类作品的自由的、公共的授权文件。

大多数软件授权申明被设计为剥夺您共享和修改软件的自由。相反地,GNU通用公共授权力图保护您分享和修改自由软件地自由——以确保软件对所有使用者都是自由的。我们,自由软件基金会,对我们的大多数软件使用GNU通用公共授权;本授权同样适用于任何其作者以这种方式发布的软件。您也可以让您的软件使用本授权。

当我们谈论自由软件时,我们指的是行为的自由,而非价格免费。GNU通用公共授权被设计为确保您拥有发布自由软件副本(以及为此收费,如果您希望的话)的自由,确保您能收到源代码或者在您需要时能获取源代码,确保您能修改软件或者将它的一部分用于新的自由软件,并且确保您知道您能做这些事情。

为了保护您的权利,我们需要做出要求,禁止任何人否认您的这些权利或者要求您放弃这些权利。因此,如果您发布此软件的副本或者修改它,您就需要肩负起尊重他人自由的责任。

例如,如果您发布自由软件的副本,无论以免费还是以收费的模式,您都必须把您获得的自由同样的给予副本的接收者。您必须确保他们也能收到或者得到源代码。而且您必须向他们展示这些条款,以使他们知道自己享有这样的权利。

使用GNU通用公共授权的开发者通过两项措施来保护您的权利:(1)声明软件的版权;(2)向您提供本授权文件以给您复制、发布并且/或者修改软件的法律许可。

为了保护软件开发者和作者,通用公共授权明确阐释自由软件没有任何担保责任。如用户和软件作者所希望的,通用公共授权要求软件被修改过的版本必须明确标示,从而避免它们的问题被错误地归咎于先前的版本。

某些设备被设计成拒绝用户安装或运行其内部软件的修改版本,尽管制造商可以安装和运行它们。这从根本上违背了通用公共授权保护用户能修改软件的自由的宗旨。此类滥用本授权的系统模式出现在了最让人无法接受的个人用户产品领域。因此,我们设计了这个版本的通用公共授权来禁止那些产品的侵权行为。如果此类问题在其他领域大量出现,我们准备好了在将来的通用公共授权版本里扩展这项规定,以保护用户的自由。

最后,每个程序都经常受到软件专利的威胁。政府不应该允许专利权限制通用计算机软件的发展和使用,但是在政府确实允许这种事情的地区,我们希望避免应用于自由软件的专利权使该软件有效私有化的危险。为了阻止这样的事情的发生,通用公共授权确保没有人能够使用专利权使得自由软件非自由化。

以下是复制,发布和修改软件的详细条款和条件。

4.1.2    条款和条件

4.1.2.1 定义

“本授权”指GNU通用公共授权第三版。

“版权”一词同样指适用于其他产品如半导体防护罩等的保护版权的法律。

“本程序”指任何在本授权下发布的受版权保护的作品。被授权人称为“您”。“被授权人”和“版权接受者”可以是个人或组织。

“修改”作品是指从软件中拷贝或者做出全部或一丁点儿的修改,这不同于逐字逐句的复制,是需要版权许可的。修改成果被称为先前作品的“修改版本”或者“基于”先前作品的软件。

“覆盖程序”指未被修改过的本程序或者基于本程序的程序。

“传播”程序指使用该程序做任何如果没有许可就会在适用的版权法下直接或间接侵权的事情,不包括在电脑上执行程序或者是做出您不与人共享的修改。传播包括复制,分发(无论修改与否),向公众共享,以及在某些国家的其他行为。

“发布”作品指任何让其他组织制作或者接受副本的传播行为。仅仅通过电脑网络和一个用户交流,且没有发送程序拷贝的行为不是发布。

一个显示“适当的法律通告”的交互的用户接口应包括这样一个方便而显著的可视部件,它具有以下功能:(1)显示一个合适的版权通告;(2)告诉用户对本程序没有任何担保责任(除非有担保明确告知),受权人可以在本授权下发布本程序,以及如果阅读本授权协议的副本。如果该接口显示了一个用户命令或选项列表,比如菜单,该列表中的选项需要符合上述规范。

4.1.2.2  源代码

“源代码”指修改程序常用的形式。“目标代码”指程序的任何非源代码形式。

“标准接口”有两种含义,一是由标准组织分支定义的官方标准;二是针对某种语言专门定义的众多接口中,在该类语言的开发者中广为使用的那种接口。

可执行程序的“系统库”不是指整个程序,而是指任何包含于主要部件但不属于该部件的部分,并且只是为了使能该部件而开发,或者为了实现某些已有公开源代码的标准接口。“主要部件”在这里指的是执行程序的特定操作系统(如果有的话)的主要的关键部件(内核,窗口系统等),或者生成该可执行程序时使用的编译器,或者运行该程序的目标代码解释器。

目标代码中的程序“对应的源代码”指所有生成,安装,(对可执行程序而言)运行该目标代码和修改该程序所需要的源代码,包括控制这些行为的脚本。但是,它不包括程序需要的系统库,通用目的的工具,以及程序在完成某些功能时不经修改地使用的那些不包括在程序中的普遍可用的自由软件。例如,对应的源代码包括与程序的源文件相关的接口定义文件,以及共享库中的源代码和该程序设计需要的通过如频繁的数据交互或者这些子程序和该程序其他部分之间的控制流等方式获得的动态链接子程序。

对应的源代码不需要包含任何拥护可以从这些资源的其他部分自动再生的资源。

源代码形式的程序对应的源代码定义同上。

4.1.2.3 基本的许可

所有在本授权协议下授予的权利都是对本程序的版权而言,并且只要所述的条件都满足了,这些授权是不能收回的。本授权明确的确认您可以不受任何限制地运行本程序的未修改版本。运行一个本授权覆盖的程序获得的结果只有在该结果的内容构成一个覆盖程序的时候才由本授权覆盖。本授权承认您正当使用或版权法规定的其它类似行为的权利。

只要您的授权仍然有效,您可以无条件地制作,运行和传播那些您不发布的覆盖程序。只要您遵守本授权中关于发布您不具有版权的资料的条款,您可以向别人发布覆盖程序,以要求他们为您做出专门的修改或者向您提供运行这些程序的简易设备。那些为您制作或运行覆盖程序的人作为您专门的代表也必须在您的指示和控制下做到这些,请禁止他们在他们和您的关系之外制作任何您拥有版权的程序的副本。当下述条件满足的时候,在任何其他情况下的发布都是允许的。转授许可证授权是不允许的,第10节让它变的没有必要了。

4.1.2.4 保护用户的合法权利不受反破解法侵犯

在任何实现1996年通过的世界知识产权组织版权条约第11章中所述任务的法律,或者是禁止或限制这种破解方法的类似法律下,覆盖程序都不会被认定为有效的技术手段的一部分。

当您发布一个覆盖程序时,您将放弃任何禁止技术手段破解的法律力量,甚至在本授权关于覆盖程序的条款下执行权利也能完成破解。同时,您放弃任何限制用户操作或修改该覆盖程序以执行您禁止技术手段破解的合法权利的企图。

4.1.2.5 发布完整副本

你可以通过任何媒介发布本程序源代码的未被修改过的完整副本,只要您显著而适当地在每个副本上发布一个合适的版权通告;保持完整所有叙述本授权和任何按照第7节加入的非许可的条款;保持完整所有的免责申明;并随程序给所有的接受者一份本授权。

您可以为您的副本收取任何价格的费用或者免费,你也可以提供技术支持或者责任担保来收取费用。

4.1.2.6 发布修改过的源码版本

您可以在第4节的条款下以源码形式发布一个基于本程序的软件,或者从本程序中制作该软件需要进行的修改,只要您同时满足所有以下条件:

  1. 制作的软件必须包含明确的通告说明您修改了它,并给出相应的修改日期。
  2. 制作的软件必须包含明确的通告,陈述它在本授权下发布并指出任何按照第7节加入的条件。这条要求修改了第4节的“保持所有通知完整”的要求。
  3. 您必须把整个软件作为一个整体向任何获取副本的人按照本授权协议授权。本授权因此会和任何按照第7节加入的条款一起,对整个软件及其所有部分,无论是以什么形式打包的,起法律效力。本授权不允许以其他任何形式授权该软件,但如果您个别地收到这样的许可,本授权并不否定该许可。
  4. 如果您制作的软件包含交互的用户接口,每个用户接口都必须显示适当的法律通告;但是,如果本程序包含没有显示适当的法律通告的交互接口,您的软件没有必要修改他们让他们显示。如果一个覆盖程序和其他本身不是该程序的扩展的程序的联合体,这样的联合的目的不是为了在某个存储或发布媒体上生成更大的程序,且联合体程序和相应产生的版权没有用来限制程序的使用或限制单个程序赋予的联合程序的用户的合法权利的时候,这样的联合体就被称为“聚集体”。在聚集体中包含覆盖程序并不会使本授权应用于该聚集体的其他部分。

4.1.2.7 发布非源码形式的副本

您可以在第4,5节条款下以目标代码形式发布程序,只要您同时以一下的一种方式在本授权条款下发布机器可读的对应的源代码:

  1. 在物理产品(包括一个物理的发布媒介)中或作为其一部分发布目标代码,并在通常用于软件交换的耐用的物理媒介中发布对应的源代码。
  2. 在物理产品(包括一个物理的发布媒介)中或作为其一部分发布目标代码,并附上有效期至少3年且与您为该产品模型提供配件或客户服务的时间等长的书面承诺,给予每个拥有该目标代码的人(1)要么在通常用于软件交换的耐用物理媒介中,以不高于您执行这种源码的发布行为所花费的合理费用的价格,一份该产品中所有由本授权覆盖的软件的对应的源代码的拷贝;(2)要么通过网络服务器免费提供这些对应源代码的访问。
  3. 单独地发布目标代码的副本,并附上一份提供对应源代码的书面承诺。这种行为只允许偶尔发生并不能盈利,且在您收到的目标代码附有第6节b规定的承诺的时候。
  4. 在指定的地点(免费或收费地)提供发布的目标代码的访问并在同样的地点以不增加价格的方式提供对应源代码的同样的访问权。您不需要要求接收者在复制目标代码的时候一道复制对应的源代码。如果复制目标代码的地点是网络服务器,对应的源代码可以在另外一个支持相同复制功能的服务器上(由您或者第三方运作),只要您在目标代码旁边明确指出在哪里可以找到对应的源代码。无论什么样的服务器提供这些对应的源代码,您都有义务保证它在任何有需求的时候都可用,从而满足本条规定。
  5. 用点对点传输发布目标代码,您需要告知其他的节点目标代码和对应的源代码在哪里按照第6节d的条款向大众免费提供。

目标代码中可分离的部分,其源代码作为系统库不包含在对应的源代码中,不需要包含在发布目标代码的行为中。

“用户产品”指(1)“消费品”,即通常用于个人的、家庭的或日常目的的有形个人财产;或者(2)任何为公司设计或销售却卖给了个人的东西。在判断一个产品是否消费品时,有疑点的案例将以有利于覆盖面的结果加以判断。对特定用户接收到的特定产品,“正常使用”指该类产品的典型的或通常的使用,无论该用户的特殊情况,或者该用户实际使用该产品的情况,或者该产品要求的使用方式如何。一个产品是否是消费品与该产品是否具有实质的经济上的、工业的或非消费品的用处无关,除非该用处是此类产品唯一的重要使用模式。

用户产品的“安装信息”指从对应源码的修改版本安装和运行该用户产品中包含的覆盖程序的修改版本所需要的任何方法、过程、授权密钥或其他信息。这些信息必须足以保证修改后的目标代码不会仅仅因为被修改过而不能继续运行。

如果您在本节条款下在用户产品中,或随同,或专门为了其中的使用,发布目标代码程序,而在发布过程中用户产品的所有权和使用权都永久地或在一定时期内(无论此项发布的特点如何)传递给了接收者,在本节所述的条款下发布的对应的源代码必须包含安装信息。但是如果您或者任何第三方组织都没有保留在用户产品上安装修改过的目标代码的能力(比如程序被安装在了ROM上),那么这项要求不会生效。

提供安装信息的要求并没有要求为接收者修改或安装过的程序,或者修改或安装该程序的用户产品,继续提供支持服务、担保或升级。当修改本身实际上相反地影响了网络的运行,或者违反了网络通信的规则和协议时,网络访问可以被拒绝。

根据本节发布的对应源代码和提供的安装信息必须以公共的文件格式发布(并附加一个该类型文档的实现方法以源码形式向公众共享),解压缩、阅读或复制这些信息不能要求任何密码。

4.1.2.8 附加条款

“附加许可”是通过允许一些本授权的特例来补充本授权的条款。只要它们在使用法律下合法,对整个程序都生效的附加许可就应当被认为是本授权的内容。如果附加许可只是对本程序的一部分生效,那么该部分可以在那些许可下独立使用,但整个程序是在本授权管理下,无论附加许可如何。

当您发布覆盖程序的副本时,您可以选择删除该副本或其部分的任何附加许可。(当您修改程序时,附加许可可能要求在某些情况下将自身删除)。您可以把附加许可放在材料上,加入到您拥有或能授予版权许可的覆盖程序中。

尽管本授权在别处有提供,对于您加入到程序中的材料,您可以(如果您由该材料的版权所有者授权的话)用以下条款补充本授权:

  1. 拒绝担保责任或以与本授权第15和16小节条款不同的方式限制责任;
  2.  要求保留特定的合理法律通告,或者该材料中或包含于适当法律通告中的该程序的作者贡献;
  3. 禁止误传该材料的来源,或者要求该材料的修改版本以合理的方式标志为与原版本不同的版本;
  4. 限制以宣传为目的的使用该材料作者或授权人的姓名;
  5. 降低授权级别以在商标法下使用一些商品名称,商标或服务标记;
  6. 要求任何发布该材料(或其修改版本)的人用对接收者的责任假设合同对授权人和材料作者进行保护,避免任何这样的假设合同直接造成授权人和作者的责任。

所有其他不许可的附加条款都被认为是第10节中的“进一步的约束”。如果您收到的程序或者其部分,声称自己由本授权管理,并补充了进一步约束,那么您可以删除这些约束。如果一个授权文件包含进一步约束,但是允许再次授权或者在本授权下发布,只要这样的进一步的约束在这样的再次授权或发布中无法保留下来,您就可以在覆盖程序中加入该授权文件条款管理下的材料。

如果您依据本小节向覆盖程序添加条款,您必须在相关的源码文件中加入一个应用于那些文件的附加条款的声明或者指明在哪里可以找到这些条款的通告。

附加的条款,无论是许可的还是非许可的条款,都可以写在一个单独的书面授权中,或者申明为例外情况;这两种方法都可以实现上述要求。

4.1.2.9 终止授权

您只有在本授权的明确授权下才能传播或修改覆盖程序。任何其它的传播或修改覆盖程序的尝试都是非法的,并将自动终止您在本授权下获取的权利(包括依据第11节第三段条款授予的任何专利授权)。

然而,如果您停止违反本授权,那么您从某个特定版权所有者处获取的授权许可能够以以下方式恢复(a)您可以暂时地拥有授权,直到版权所有者明确地终止您的授权;(b)如果在您停止违反本授权后的60天内,版权所有者没有以某种合理的方式告知您的违背行为,那么您可以永久地获取该授权。

进一步地,如果某个版权所有者以某种合理的方式告知您违反本授权的行为,而这是您第一次收到来自该版权所有者的违反本授权的通知(对任何软件),并且在收到通知后30天内修正了违反行为,那么您从该版权所有者处获取的授权将永久地恢复。

当您的授权在本节条款下被终止时,那些从您那获取授权的组织只要保持不违反本授权协议,其授权就不会被终止。您只有在授权被版权所有者恢复了之后才有资格依据第10节的条款获取该材料的新的授权。

4.1.2.10         获取副本不需要接受本授权

您不需要为了接收或运行本程序的副本而接受本授权协议。仅仅是因为点对点传输获取副本引起传播行为,也不要求您接受本授权协议。然而,除了本授权外,任何授权协议都不能授予您传播或修改覆盖程序的许可。因此,如果您修改或者传播了本程序的副本,那么您就默认地接受了本授权。

4.1.2.11         下游接收者的自动授权

每次您发布覆盖程序,接收者都自动获得一份来自原授权人的依照本授权协议运行、修改和传播该程序的授权。依据本授权,您不为执行任何第三方组织的要求负责。

“实体事务”指转移一个组织的控制权或全部资产,或者拆分组织,或者合并组织的事务。如果覆盖程序的传播是实体事务造成的,该事务中每一个接收本程序副本的组织都将获取一份其前身拥有的或者能够依据前面的条款提供的任何授权,以及从其前身获取程序对应的源代码的权利,如果前身拥有或以合理的努力能够获取这些源代码的话。

您不可以对从本授权协议获取或确认的权利的执行强加任何约束。比如,您不可以要求授权费用,版税要求或对从本授权获取的权利的执行收取任何费用。您不可以发起诉讼(包括联合诉讼和反诉)声称由于制作、使用、销售、批发或者引进本程序或其任何一部分而侵犯了任何专利权。

4.1.2.12         专利权

“贡献者”是在本授权下授予本程序或者本程序所基于的程序的使用权的版权所有者。这样的程序被成为贡献者的“贡献者版本”。

一个贡献者的“实质的专利申明”是该贡献者所占有和控制的全部专利,无论已经获得的还是在将来获得的,那些可能受到某种方式侵犯的专利权。本授权允许制作、使用和销售其贡献者版本,但不包括那些只会由于对贡献者版本进一步的修改而受到侵犯的专利的申明。为此,“控制”一词包括以同本授权要求一致的方式给予从属授权的权利。

每个贡献者在该贡献者的实质的专利申明下授予您非独家的,全世界的,不需要版税的专利授权,允许您制作、使用、销售、批发、进口以及运行、修改和传播其贡献者版本内容。

在以下三个自然段中,“专利授权”指任何形式表达的不执行专利权的协议或承诺(例如使用专利权的口头许可,或者不为侵犯专利而起诉的契约)。向一个组织授予专利授权指做出这样的不向该组织提出强制执行专利权的承诺。

如果您在自己明确知道的情况下发布基于某个专利授权的覆盖程序,而这个程序的对应的源代码并不能在本授权条款下通过网络服务器或其他有效途径免费地向公众提供访问,您必须做到:(1)使对应的源代码按照上述方法可访问;或者(2)放弃从该程序的专利授权获取任何利益;或者(3)以某种与本授权要求一致的方法使该专利授权延伸到下游的接收者。“在自己明确知道的情况下”指您明确地知道除了获取专利授权外,在某个国家您传播覆盖程序的行为,或者接收者使用覆盖程序的行为,会由于该专利授权而侵犯一个或多个在该国可确认的专利权,而这些专利权您有足够的理由相信它们是有效的。

在依照或者涉及某一次事务或安排时,如果您通过获取发布或传播覆盖程序的传输版本,并给予接收该覆盖程序的某些组织专利授权,允许他们使用,传播,修改或者发布该覆盖程序的特殊版本,那么您赋予这些组织的专利授权将自动延伸到所有该覆盖程序及基于该程序的作品的接收者。

一份专利授权是“有偏见的”,如果它没有在自身所覆盖的范围内包含,禁止行使,或者要求不执行一个或多个本授权下明确认可的权利。以下情况,您不可以发布一个覆盖程序:如果您与软件发布行业的第三方组织有协议,而该协议要求您根据该程序的发布情况向该组织付费,同时该组织在你们的协议中赋予任何从您那里获得覆盖软件的组织一份有偏见的专利授权,要么(a)连同您所发布的副本(或者从这些副本制作的副本);要么(b)主要为了并连同某个的产品或者包含该覆盖程序的联合体。如果您签署该协议或获得该专利授权的日期早于2007年3月28日,那么您不受本条款约束。

本授权的任何部分不会被解释为拒绝或者限制任何暗含的授权或其他在适用专利权法下保护您的专利不受侵犯的措施。

4.1.2.13         不要放弃别人的自由

如果您遇到了与本授权向矛盾的情况(无论是法庭判决,合同或者其他情况),它们不能使您免去本授权的要求。如果您不能同时按照本授权中的义务和其他相关义务来发布覆盖程序,那么您将不能发布它们。比如,如果您接受了要求您向从您这里或许本程序的人收取版税的条款,您唯一能够同时满足本授权和那些条款的方法是完全不要发布本程序。

4.1.2.14         和GNU Affero通用公共授权一起使用

尽管本协议有其他防备条款,您有权把任何覆盖程序和基于第三版GNU Affero通用公共授权的程序链接起来,并且发布该联合程序。本授权的条款仍然对您的覆盖程序有效,但是GNU Affero通用公共授权第13节关于通过网络交互的要求会对整个联合体有效。

4.1.2.15         本授权的修订版

自由软件基金会有时候可能会发布GNU通用软件授权的修订版本和/或新版本。这样的新版本将会和现行版本保持精神上的一致性,但是可能会在细节上有所不同,以处理新的问题和情况。

每个版本都有一个单独的版本号。如果本程序指出了应用于本程序的一个特定的GNU通用公共授权版本号“以及后续版本”,您将拥有选择该版本或任何由自由软件基金会发布的后续版本中的条款和条件的权利。如果本程序没有指定特定的GNU通用公共授权版本号,那么您可以选择任何自由软件基金会已发布的版本。

如果本程序指出某个代理可以决定将来的GNU通用公共授权是否可以应用于本程序,那么该代理的接受任何版本的公开称述都是您选择该版本应用于本程序的永久认可。

后续的授权版本可能会赋予您额外的或者不同的许可。但是,您对后续版本的选择不会对任何作者和版权所有者强加任何义务。

4.1.2.16         免责申明

在适用法律许可下,本授权不对本程序承担任何担保责任。除非是书面申明,否则版权所有者和/或提供本程序的第三方组织,“照旧”不承担任何形式的担保责任,无论是承诺的还是暗含的,包括但不限于就适售性和为某个特殊目的的适用性的默认担保责任。有关本程序质量与效能的全部风险均由您承担。如本程序被证明有瑕疵,您应承担所有必要的服务、修复或更正的费用。

4.1.2.17         责任范围

除非受适用法律要求或者书面同意,任何版权所有者,或任何依前述方式修改和/或发布本程序者,对于您因为使用或不能使用本程序所造成的一般性、特殊性、意外性或间接性损失,不负任何责任(包括但不限于,资料损失,资料执行不精确,或应由您或第三人承担的损失,或本程序无法与其他程序运作等),即便该版权所有者或其他组织已经被告知程序有此类损失的可能性也是如此。

4.1.2.18         第15和16节的解释

如果上述免责申明和责任范围不能按照地方法律条款获得法律效力,复审法庭应该采用最接近于完全放弃关于本程序的民事责任的法律,除非随同本程序的责任担保或责任假设合同是收费的。

4.1.3    如何在您的新程序中应用这些条款?

如果您开发了一个新程序,并且希望能够让它尽可能地被大众使用,达成此目的的最好方式就是让它成为自由软件。任何人都能够依据这些条款对该软件再次发布和修改。

为了做到这一点,请将以下声明附加到程序上。最安全的作法,是将声明放在每份源码文件的起始处,以有效传达无担保责任的讯息;且每份文件至少应有「版权」列以及本份声明全文位置的提示。

<用一行描述程序的名称与其用途简述>

版权所有(C) <年份><作者姓名>

本程序为自由软件;您可依据自由软件基金会所发表的GNU通用公共授权条款,对本程序再次发布和/或修改;无论您依据的是本授权的第三版,或(您可选的)任一日后发行的版本。

本程序是基于使用目的而加以发布,然而不负任何担保责任;亦无对适售性或特定目的适用性所为的默示性担保。详情请参照GNU通用公共授权。

您应已收到附随于本程序的GNU通用公共授权的副本;如果没有,请参照<http://www.gnu.org/licenses/>.同时附上如何以电子及书面信件与您联系的资料。

如果程序进行终端交互方式运作,请在交互式模式开始时,输出以下提示:

<程序> 版权所有(C) <年份> <作者姓名>

本程序不负任何担保责任,欲知详情请键入’show w’。

这是一个自由软件,欢迎您在特定条件下再发布本程序;欲知详情请键入’show c’。

所假设的指令’show w’与’show c’应显示通用公共授权的相对应条款。当然,您可以使用’show w’与’show c’以外的指令名称;对于图形用户界面,您可以用“关于”项代实现此功能。

如有需要,您还应该取得您的雇主(若您的工作为程序设计師)或学校就本程序所签署的“版权放弃承诺书”。欲知这方面的详情,以及如何应用和遵守GNU通用公共授权,请参考<http://www.gnu.org/licenses/>

GNU通用公共授权并不允许您将本程序合并到私有的程序中。若您的程序是一个子程序库,您可能认为允许私有的应用程序链接该库会更有用。如果这是您所想做的,请使用GNU松弛通用公共授权代替本授权。但这样做之前,请阅读<http://www.gnu.org/philosophy/why-not-lgpl.html>

4.2     LGPL 2.1协议

4.2.1    导言

大多数软体许可证决意剥夺您共享和修改软体的自由。相反的,GNU 通用公共许可证力图保证您共享和修改自由软体的自由 —— 保证自由软体对所有使用者都是自由的。

这个许可证,较宽松公共许可证,适用于一些由自由软体基金会与其他决定使用此许可证的软体作者,所特殊设计的软体套件 —— 象是函数库。您也可以使用它,但我们建议您事先仔细考虑,基于以下的说明是否此许可证或原来的通用公共许可证在任何特殊情况下均为较好的方案。

当我们谈到自由软体时,我们所指的是自由,而不是价格。我们的 GNU 通用公共许可证是设计用以确保使您有发布自由软体备份的自由(如果您愿意,您可以对此项服务收取一定的费用);确保您能收到程式原始码或者在您需要时能得到它;确保您能修改软体或将它的一部分用于新的自由软体;而且还确保您知道您可以做上述的这些事情。

为了保护您的权利,我们需要作出限制:禁止任何人否认您上述的权利,或者要求您放弃这些权利。如果您发布软件的副本,或者对之加以修改,这些规定就转化为您的责任。

例如,如果您发布此函数库的副本,不管是免费还是收取费用,您必须将您享有的一切权利给予接受者;您必须确保他们也能收到或得到原始程式码;如果您将此函数库与其他的程式码连结,您必须提供完整的目的对象文件和程序(object file)给接受者,则当他们修改此函数库并重新编译过后,可以重新与目的档连结。您并且要将这些条款给他们看,使他们知道他们有这样的权利。

我们采取两项措施来保护您的权利: (1)用版权来保护函数库。并且,(2)我们提供您这份许可证,赋予您复制,发布和(或)修改这些函数库的法律许可。

为了保护每个发布者,我们需要非常清楚地让每个人明白,自由函数库是没有担保责任的。如果由于某人修改了函数库,并继续加以传播,我们需要它的接受者明白:他们所得到的并不是原始的版本。故由其他人引入的任何问题,对原作者的声誉将不会有任何的影响。

最后,由于软体专利不断地威胁自由软体的存在,我们希望商业公司无法藉由自专利持有者取得一个受限的许可证,而有效地限制自由软体的使用者。因此,我们坚持一个函数库所能取得的任何专利,必须与本许可证所声明的“完全自由使用”一致。

大部分的 GNU 软体,包括一些函数库,是受到原来的 GNU 通用公共许可证的保护。本许可证, GNU 较宽松通用公共许可证,适用于特殊设计的函数库,且与原来的通用公共许可证有很大的不同。我们在特定的函数库中使用它,以准许非自由的程式可以与这些函数库连结。当一个程式与一个函数库连结,不论是静态连结或使用共享函数库,二者的结合可以合理地说是结合的作品,一个原来的函数库的衍生品。因此,原来的通用公共许可证只有在整个结合品满足其自由的标准时,才予许连结。较宽松通用公共许可证则以更宽松的标准允许其他程式码与本函数库连结。

我们称此许可证 “较宽松” 通用公共许可证,是因为它比起原来的通用公共许可证对使用者的自由做到较少的保护。在与非自由软体竞争时,它也提供其他自由软体的写作者较少的优势。这些不利之处正是我们使用原来的通用公共许可证于许多函数库的理由。然而,较宽松的许可证可在某些特殊场合下带来好处。例如,在少数情况下,可能会有特殊的需要而鼓励大家尽可能广泛地使用特定的函数库,因而使它成为实际上的标准。为了达到此目标,必须允许非自由的程式使用此函数库。一个较常发生的情况是一个自由的函数库与一个被广泛使用的非自由函数库做相同的工作,在此情况下,限制只有自由软体可以使用此自由函数库不会有多少好处,故我们如用了较宽松通用公共许可证。

在其他情况下,允许非自由程式使用特定的函数库,可以让更多的人们使用自由软体的大部分。例如,允许非自由程式使用 GNU C 函数库可以让更多的人们使用整个 GNU 作业系统,以及它的变形,GNU/Linux 作业系统。

尽管较宽松通用共公许可证对使用者的自由是较少的保护的,它却能确保与此函数库连结的程式的使用者拥有自由,而且具有使用修改过的函数库版本来执行该程式的必要方法。

以下是复制、发布、以及修改的精确条款与条件。请注意 “基于函数库的作品” 以及 “使用函数库的作品” 之间的差异:前者包含来自函数库修改过的原始码;而后者则必须与函数库结合才能执行。

4.2.2    条款和条件

4.2.2.1 定义

  1. 本许可证适用于任何软体函数库,或其他包含了由版权所有者加入的注意事项的程式,或其他有公信力的团体宣称其程式可以在较宽松通用公共许可证 (也称之为 “本许可证”) 的条款下发布。每一位许可证接受者以 “您” 来称呼。
  2. 一个 “函数库” 意指一些软体函数的集合,以及或准备好的资料以方便与应用程式 (其使用了其中某些函数与资料) 连结形成可执行的程式。以下,”函数库” 一词指的是任何在本条款下发布的这一类软体函数库或作品,个 “基于本函数库的作品” 意指函数库或任何在版权法下的衍生作品:也就是说,一个包含了本函数库或其一部分的作品,可以是原封不动的,或经过修改的,和/或直接翻译成其他语言的。 (在下文中,翻译是不受限地包含在 “修改” 的条款中。)
  3. 作品的 “原始码” 意指对作品进行修改最优先择取的形式。对函数库而言,完整的原始码意指所有模组的所有原始程式,加上有关的介面的定义,加上控制函数库的安装和编译的 script。
  4. 本许可证条款不适用于复制,发布和修改以外的活动。这些活动超出这些条款的范围。使用本函数库来执行本程式的动作不受条款的限制,而程式的输出只有在其内容所构成的作品是基于本函数库时 (与在什么样的工具中使用本函数库来输出无关) ,这一条款才适用。以上是否为真则取决于本函数库具体用来做什么。
  5. 只要您在每一程式副本上明显和恰当地宣告版权声明和不承担担保的声明,并保持此许可证的声明和没有担保的声明完整无损,并和程式一起给其他每位程式接受者一份许可证的副本,您就可以用任何媒体复制和发布您收到的函数库的完整原始码。您可以为转让副本的实际行动收取一定费用。您也可以选择提供担保以换取一定的费用。
  6. 只要您同时满足下面的所有条件,您就可以按前面第一款的要求修改函数库的一个或几个副本或它的任何部分,以此形成基于此函数库的作品,并且复制和发布这一经过修改的程式或作品:

4.2.2.2  条款

1)     被修改的作品本身必须是一个软体函数库。

2)     您必须在修改过的档案中附有明确的说明:

3)     您修改了此一档案及任何修改的日期。您必须让整个作品允许第三方在此许可证条款下可以免费使用。

4)     如果修改过的函数库其某个设备使用到了「使用本函数库的应用程式」所提供的函数或资料表格,却不是当此设备被呼叫时以参数列传入时,则您必须确实做到,当应用程式不提供这样的函数或表格时,则此设备依旧能工作,且其执行的任何目的仍然有意义。

5)     (例如,一个函数库的函数用来计算平方根,其目的是有完整的定义且与应用程式是无关的。因此, 2d 小节要求任何本函数会使用的,由应用程式所提供的函数或表格必须是选择性的:如果应用程式不提供的话,则计算平方根的函数必须依旧能计算平方根)

这些要求适用于整个修改过的作品。如果能够确定作品的一部分并非本函数库的衍生产品,且可以合理地单独考虑并将它与原作品分开的话,则当您将它作为独立的作品发布时,它不受此许可证和其条款的约束。但是当您将这部分与基于本函数库的作品一同发布时,则整个套件将受到本许可证条款约束,其对于其他许可证持有人的使用范围扩大到整个产品,也就是套件的每个部分,不管它是谁写的。

因此,本条款的意图不在于索取权利,或剥夺完全由您完成的作品的权利,而是履行权利来控制基于本函数库的集体作品或衍生作品的发布。 此外,将与本函数库无关的作品和本函数库 (或基于本函数库的作品) 一起放在贮存媒体或发布媒体的同一卷上,并不导致将其他作品置于此许可证的约束范围之内。

  1. 对于一个函数库的副本,您可以选择性地使用原来的 GNU 通用公共许可证上的条款来取代本许可证上的条款。如果您要这么做,您必须修改所有的参考到本许可证的注意事项,使它们指向原来的 GNU 通用公共许可证,第二版,以取代本许可证(如果有比第二版的原来的 GNU 通用公共许可证更新的版本出现的话,则如果您愿意的话可以特别指明使用新版)。请不要对这些注意事项做出其他的改变。一旦在一个副本上做了这样的改变,则该副本就无法撤回这样的改变,故原来的 GNU 通用公共许可证将适用于所有后续的副本以及由此副本衍生出来的作品。此一选择性适用于当您想要将一部分的函数库原始码复制到一个非函数库的程式使用时。
  2. 您可以以目标码或可执行形式复制或发布本函数库 (或符合第 2 款,基于本函数库的作品),只要您遵守前面的第 1、2 款,并同时提供完整的相关机器可读的原始码,而这些原始码必须在前面的第 1 与第 2 款条件下,在一般习惯上用来做软体交换的媒体上发布。如果所发布的目标码是由指定的地点提供拷贝索取,那么由同一地点所提供等价的原始码拷贝索取可以算作原始码的发布,即使第三方不强求与目标码一起复制原始码。
  3. 一个程式若包含不经任何部分修改的函数库,但却是设计经由编译或连结的方式与本函数库一同工作者,称之为 “使用函数库的作品”。这样的一个作品,严格地说,并非本函数库的衍生作品,因而不在本许可证的范围之内。然而,将 “使用函数库的作品” 与本函数库连结而产生可执行程式,则是本函数库的衍生品 (因为它包函了本函数库的一部分),而不是 “使用函数库的作品”,因此其可执行程式包含在本许可证的范围内。第 7 款说明了发布此可执行程式的条款。

当 “使用函数库的作品” 使用了函数库部分的标头档内容时,则此作品即使其原始码不属于本函数库的衍生品,但其目标码仍然是。这一点是否为真特别在是否本作品可以在不需要本函数库即可连结,或者是否该作品本身也是一个函数库时特别明显。

如果这样的目标档只使用数字参数、资料结构层级与附属品、以及小巨集和小内□式 (小于或等于十行) ,则此目标档的使用是不受限的,不论是否它是合法的衍生作品。 (但可执行程式若包函此目标档以及一部分的函数库,仍然将在第 7款的规定下)

否则的话,如果本作品是本函数库的衍生品,您必须在第 6 款的规定下发布该作品的目标码。任何包含该作品的可执行程式也在第 6 款的范围内,不论它们是否直接与本函数库连结。

  1. 做为上述条款的例外情况,您也可以将 “使用函数库的作品” 与本函数库结合或连结,以产生包含部分本函数库的作品,并在允许使用者自身使用时可以修改该作品,以及在对修改进行反组译除错的情况下,您可以依照您的选择发布该作品。

您必须在每个作品的副本突显出如下的注意事项:本函数库在作品中被使用,以及本函数库以及它的使用是在本许可证的规定下。您必须提供本许可证的副本。如果该作品在执行时显示版权声明,您必须在其中包含本函数库的版权声明,以及指引使用者取得本许可证的副本。同时,您必须做到以下其中一件事:

必须将完整的机器可读的函数库原始码包含在该作品中,包括任何该作品使用到的改变 (这些改变必须在前述第 1 与第 2 款的要求下发布);而且,如果该作品是一个与函数库连结的「完整的、机器可□的 “使用函数库的作品”」,则要有目标码和/或原始码,如此使用者可以修改本函数库且可以重新连结,以产生包函修改过的函数库的修改过的可执行程式。 (理所当然的若使用者修改了函数库的档案定义内容时,则该作品不必然可以重新编译以使用修改过的定义。)

在与函数库连结时使用适当的分享函数库连结机制。一个适当的机制是: (1) 在执行时使用已存在于使用者的电脑中的函数库副本,而不是将函数库的函数复制到可执行程式里,以及 (2) 如果使用者安装了一份修改过的函数库,只要修改过的版本在介面上与该作品在编译连结时所用的版本是相容的,则该执行程式可以与修改过的函数库运作良好。

在该作品内提供书面报价,有效期不少于三年,以提供同样的使用者上述第 7a 款中的内容,费用不得超过该程式发布的实际成本。 如果所发布的作品是由指定的地点提供拷贝索取,则由同一地点提供上述内容的等价拷贝索取。

确定使用者已经收到该作品的一份复制,或是您已经寄给该使用者一份复制品。

对于一个可执行程式,其所需的 “使用函数库的作品” 的形式必须包括任何要从中再产生可执行程式时所需的资料与工具程式。然而,有一个特殊例外,其所发布的内容不需要包括任何一般与「可执行本程式的作业系统」的主要部分 (如编译器、核心等) 一起发布的部分 (不论是原始码或可执行码),除非这些组成部分和可执行作品结合在一起。

有一个可能情况是,这些要求与其他通常不与作业系统在一起的私有函数库的版权限制相抵触,这样的抵触表示您不能将它们与本函数库一起用于您发布的可执行程式中。

  1. 您可以将使用本函数库的函数库设备,以及其他不在本许可证范围内的函数库,对等地放入一个单独的函数库中,并在基于本函数库的作品以及其他函数库在其他状态下同意可以个别发布,以及您做到以下两点的情况下,您可以发布此结合的函数库:将基于本函数库的作品单独不与其他函数库设备结合地,与此结合的函数库一同发布。该作品必须在上述条款的规定下发布。在此结合的函数库中明显地指出其中一部分的作品是基于本函数库,并且说明那里可以找到同样不具结合形式的作品。
  2. 除非您明确按许可证提出的要求去做,否则您不能复制、修改、转发许可证、与本函数库连结、和发布本函数库。任何试图用其他方式复制、修改、转发许可证、与本函数库连结、和发布本函数库是无效的,而且将自动结束许可证赋予您的权利。然而,对那些从您那里按许可证条款得到副本和权利的人们,只要他们继续全面履行条款,许可证赋予他们的权利仍然有效。
  3. 您没有在许可证上签字,因而您没有必要一定接受此一许可证。然而,没有任何其他东西赋予您修改和发布本函数库及其衍生作品的权利。如果您不接受许可证,这些行为是法律禁止的。因此,如果您修改或发布函数库 (或任何基于函数库的作品) ,您就表明您接受这一许可证以及它的所有有关复制、发布和修改本函数库或基于它的作品的条款和条件。
  4. 每当您重新发布函数库 (或任何基于函数库的作品) 时,接受者自动从原始许可证颁发者那里接到受这些条款和条件支配的复制、发布、连结或修改本函数库的许可。您不可以强迫接受者履行除了这里赋予他们的权利之外的其他限制。您也没有强求第三方履行许可证条款的义务。
  5. 如果由于法院判决或违反专利的指控或任何其他原因 (不限于专利问题) 的结果,使得强加于您的条件 (不管是法院判决,协议书或其他) 和许可证的条件有冲突时,他们也不能令您背离许可证的条款。在您不能同时满足本许可证规定的义务及其他相关的义务来发布函数库时,则结果您只能够根本不发布函数库。例如,如果某一专利许可证不允许所有直接或间接从您那里接受副本的人们,在不付专利费的情况下重新发布函数库,唯一能同时满足两方面要求的办法是停止发布函数库。

如果本条款的任何部分在特定的环境下无效或无法实施,就使用条款的其余部分,并将这部分条款作为整体用于其他环境。本条款的目的不在于引诱您侵犯专利或其他财产权的要求,或争论这种要求的有效性。本条款的主要目的在于保护自由软体发布系统的完整性。它是通过公共许可证的应用来实现的。许多人已依赖同是出自此系统的应用程式,经由此系统发布大量自由软体而做出慷慨的供献。作者/捐献者有权决定他/她是否通过任何其他系统发布软体,许可证持有人不能强加这种选择。

本节的目的在于明确说明许可证其余部分可能产生的结果。

  1. 如果由于专利或者由于有版权的介面问题使函数库在某些国家的发布和使用受到限制,则在许可证约束下的原始版权拥有者可以增加发布地区的限制条款,将这些国家明确排除在外,并在这些国家以外的地区发布函数库。在这种情况下,许可证套件含的限制条款和许可证正文一样有效。 13. 自由软体基金会可能随时出版较宽松通用公共许可证的修改版或新版。新版和当前的版本在原则上保持一致,但在提到新问题时或有关事项时,在细节上可能出现差别。

每一版本都有不同的版本号。如果函数库指定可适用的许可证版本号以及 “任何更新的版本” ,您有权选择遵循指定的版本或自由软体基金会以后出版的新版本。如果函数库未指定许可证版本,您可选择自由软体基金会已经出版的任何版本。

  1. 如果您愿意将函数库的一部分结合到其他自由程式中,而它们的发布条件不同,请写信给作者,要求准予使用。如果是自由软体基金会加以版权保护的软体,写信给自由软体基金会,我们有时会作为例外的情况处理。我们的决定受两个主要目标的指导,这两个主要目标是:我们的自由软体的衍生作品继续保持自由状态,以及从整体上促进软体的共享和重复利用。
  2. 没有担保

1)     由于函数库准予免费使用,在适用法准许的范围内,对函数库没有担保。除非另有书面说明,版权所有者和/或其他提供函数库的人们 “一样” 不提供任何类型的担保,不论是明确的,还是隐含的,包括但不限于可销售和适合特定用途的隐含保证。全部的风险,如函数库的质量和性能问题都由您来承担。如果函数库出现缺陷,您应当承担所有必要的服务、修复和改正的费用。

2)     除非适用法或书面协议的要求,在任何情况下,任何版权所有者或任何按许可证条款修改和发布函数库的人们都不对您的损失负有任何责任。包括由于使用或不能使用函数库引起的任何一般的、特殊的、偶然发生的或重大的损失 (包括但不限于数据的损失,或者数据变得不精确,或者您或第三方的持续的损失,或者函数库不能和其他软体协调运行等) 。即使版权所有者和其他人提到这种损失的可能性也不例外。

 

 

Linux下svn命令大全

linux下svn命令大全

1、将文件checkout到本地目录  svn checkout path(path是服务器 上的目录) 例如:svn checkout svn://192.168.1.1/pro/domain 简写:svn co

2、往版本库中添加新的文件  svn add file 例如:svn add test.php(添加test.php) svn add *.php(添加当前目录下所有的php文件)

3、将改动的文件提交到版本库  svn commit -m “LogMessage“ [-N] [—no-unlock] PATH(如果选择了保持锁,就使用–no-unlock开关) 例如:svn commit -m “add test file for my test“ test.php 简写:svn ci

4、加锁/解锁  svn lock -m “LockMessage“ [—force] PATH 例如:svn lock -m “lock test file“ test.php svn unlock PATH

5、更新到某个版本  svn update -r m path 例如: svn update如果后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本 。 svn update -r 200 test.php(将版本库中的文件test.php还原到版本200) svn update test.php(更新,于版本库同步。如果在提交的时候提示过期的话,是因为冲突,需要先update,修改 文件,然后清除svn resolved,最后再提交commit) 简写:svn up

6、查看文件或者目录状态  1)svn status path(目录下的文件和子目录的状态,正常状态不显示) 【?:不在svn的控制中;M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁定】 2)svn status -v path(显示文件和子目录状态) 第一列保持相同,第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人。 注:svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的,原因是svn在本地的.svn中保留了本地版本的原始拷贝。 简写:svn st

7、删除 文件  svn delete path -m “delete test fle“ 例如:svn delete svn://192.168.1.1/pro/domain/test.php -m “delete test file” 或者直接svn delete test.php 然后再svn ci -m ‘delete test file‘,推荐使用这种 简写:svn (del, remove, rm)

8、查看日志  svn log path 例如:svn log test.php 显示这个文件的所有修改记录,及其版本号的变化

9、查看文件详细信息  svn info path 例如:svn info test.php

10、比较差异  svn diff path(将修改的文件与基础版本比较) 例如:svn diff test.php svn diff -r m:n path(对版本m和版本n比较差异) 例如:svn diff -r 200:201 test.php 简写:svn di

11、将两个版本之间的差异合并到当前文件  svn merge -r m:n path 例如:svn merge -r 200:205 test.php(将版本200与205之间的差异合并到当前文件,但是一般都会产生冲突,需要处理一下)

12、SVN 帮助  svn help svn help ci ——————————————————————————

以上是常用命令,下面写几个不经常用的

——————————————————————————

13、版本库下的文件和目录列表  svn list path 显示path目录下的所有属于版本库的文件和目录 简写:svn ls

14、创建纳入版本控制下的新目录  svn mkdir: 创建纳入版本控制下的新目录。 用法: 1、mkdir PATH… 2、mkdir URL… 创建版本控制的目录。 1、每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增 调度,以待下一次的提交。 2、每个以URL指定的目录,都会透过立即提交于仓库中创建。 在这两个情况下,所有的中间目录都必须事先存在。

15、恢复本地修改  svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert: 用法: revert PATH… 注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复 被删除的目录

16、代码 库URL变更  svn switch (sw): 更新工作副本至不同的URL。 用法: 1、switch URL [PATH] 2、switch –relocate FROM TO [PATH…]

1、更新你的工作副本,映射到一个新的URL,其行为跟“svn update”很像,也会将 服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的 方法。 2、改写工作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动 (比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同一目录时使用 这个命令更新工作副本与仓库的对应关系。 我的例子:svn switch —relocate http://59.41.99.254/mytt http://www.mysvn.com/mytt 

17、解决 冲突  svn resolved: 移除工作副本的目录或文件的“冲突”状态。 用法: resolved PATH… 注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的 相关文件,然后让 PATH 可以再次提交。

18、输出指定文件或URL的内容。  svn cat 目标[@版本]…如果指定了版本,将从指定的版本开始查找。 svn cat -r PREV filename > filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)

19、 查找工作拷贝中的所有遗留的日志文件,删除进程中的锁 

当Subversion改变你的工作拷贝(或是.svn 中 的任何信息),它会尽可能的小心,在修改任何事情之前,它把意图写到日志文件中去,然后执行log文件中的命令,然后删掉日志文件,这与分类帐的文件系统 架构类似。如果Subversion的操作中断了(举个例子:进程被杀死了,机器死掉了),日志文件会保存在硬盘上,通过重新执行日志文 件,Subversion可以完成上一次开始的操作,你的工作拷贝可以回到一致的状态。

这就是svn cleanup 所作的:它查找工作拷贝中的所有遗留的日志文件,删除进程中的锁。如果Subversion告诉你工作拷贝中的一部分已经“锁定 ”了,你就需要运行这个命令了。同样,svn status 将会使用L 显示锁定的项目:

$ svn status
 L somedir
 M somedir/foo.c 
 
 $ svn cleanup
 $ svn status
 M somedir/foo.c
 
 20、  拷贝用户的一个未被版本化的目录树到版本库。
 

svn import 命令是拷贝用户的一个未被版本化的目录树到版本库最快的方法,如果需要,它也要建立一些中介文件。

$ svnadmin create /usr/local/svn/newrepos $ svn import mytree file:///usr/local/svn/newrepos/some/project Adding mytree/foo.c Adding mytree/bar.c Adding mytree/subdir Adding mytree/subdir/quux.h Committed revision 1.

在上一个例子里,将会拷贝目录mytree 到版本库的some/project 下:

$ svn list file:///usr/local/svn/newrepos/some/project bar.c foo.c subdir/

注意,在导入之后,原来的目录树并没有 转化成工作拷贝,为了开始工作,你还是需要运行svn checkout 导出一个工作拷贝。

另附:为SVN 加入Email通知  可以通过Subversion的Hook脚本的方式为SVN 加入邮件列表功能  编译安装了Subversion后 在源码的tools 下有一个comm-email.pl的Perl脚本,在你的档案目录下有一个hooks目录,进入到hooks目录把post-commit.tmpl 改名为post-commit并给它可执行的权限。  更改post-commit脚本 把comm-email.pl脚本的决对路径加上,否则 SVN 找不到comm-email.pl 

REPOS=“$1”  REV=”$2”  /usr/local/svn /resp/commit-email.pl “$REPOS” “$REV” email@address1.com email@address2.com 

log-commit.py —repository “$REPOS” —revision “$REV” 

最后一行是用来记日志的 我不用这个功能 所以注释掉了

Rails 3.1 Engines – Mountable or Full? – Part 2

Rails 3.1 Engines – Mountable or Full? – Part 2

This is a continuation of my post Rails 3.1 Engines – Mountable or Full? – Part 1 which highlights some key features of a full engine. There are a few differences with a mountable engine, which I will try to explain below.

Mountable Engines

Engine Details

To generate a mountable engine, run rails plugin new myengine --mountable on the console. This will generate the engine’s basic structure. The first difference I noted with a mountable engine is that, by default, the engine is namespaced. The engine’s starting config is:
1
2
3
4
5
6
7
module MyEngine
# my_engine/lib/my_engine/engine.rb
 
  class Engine < Rails::Engine
    isolate_namespace MyEngine
  end
end
Since the engine has an isolated namespace, the controllers, models, helpers, etc. are all bundled within the module MyEngine. The folder structure reflects this change as well. Unlike a full engine, the mountable engine generated the typical assets that are normally associated with a Rails application, namely application.js, application.css, and application_controller.rb. Note the namespacing that occurs with the application controller:
1
2
3
4
5
6
# my_engine/app/controllers/my_engine/application_controller.rb
 
module MyEngine
  class ApplicationController < ActionController::Base
  end
end
This namespacing occurs throughout the engine. There are subtle differences in terms of routing as well. With a mountable engine, the engine’s route file looks like this:
1
2
3
4
5
# my_engine/config/routes.rb
 
MyEngine::Engine.routes.draw do
  # route stuff goes here
end
Remember, the full application’s routes start with Rails.application.routes.draw. The dummy application’s routes file was generated as:
1
2
3
4
5
6
# my_engine/test/dummy/config/routes.rb
 
Rails.application.routes.draw do
 
  mount MyEngine::Engine => "/my_engine"
end
Notice that the engine is bundled under a “mounted” route at /my_engine. This means that all of the engine’s functionality will be located under the engine’s root location of /my_engine within the dummy (parent) application. This type of structure suggests that a mountable engine is best suited for situations when a developer wants the engine to behave as its own application operating in parallel with the parent application. Most of the engine’s features are isolated and independent of the parent application. To test this, I plugged the mountable engine into a test application.

Routing

I used a model within the engine called “Post”, along with the migration, controller, and helper to match (rails generate scaffold post title:string body:text). Now my engine’s routes file looks like this:
1
2
3
4
5
# my_engine/config/routes.rb
 
MyEngine::Engine.routes.draw do
  resources :posts
end
With a full engine, the Post routes were included directly into the parent application automatically. This time, using the mountable engine and running rake routes within the parent application, nothing happened! That’s because I did not mount the engine in a similar manner to what the dummy application in our engine is using. The parent application’s route file had to be adjusted like so:
1
2
3
4
5
# parent_app/config/routes.rb
 
ParentApp::Application.routes.draw do
 mount MyEngine::Engine => "/my_engine"
end
rake routes now produced the following:
1
my_engine  /my_engine {:to=>MyEngine::Engine}
…and that’s it. All of the engine’s functionality is bundled into the parent application underneath the route /my_engine. After running rake my_engine:install:migrations and rake db:migrate in the parent application, I was ready to test how the engine’s controllers and helpers would integrate. [note: running migrations from an isolated engine will prefix your database tables with the engine name]. As with the full engine, I established a simple view template:
1
2
3
# my_engine/app/views/my_engine/posts/index.html.erb
 
<p>Hi There!</p>
Of course, navigating to /my_engine/posts in the parent application showed an almost blank page with the words “Hi There!” The controller actions and views from the engine were incorporated into the parent application, but only under the namespaced route /my_engine. Next, I tested if the view could be overridden by the parent application. I created a new view template for the Post index action within the parent application that looked like this:
1
2
3
# parent_app/app/views/posts/index.html.erb
 
<p>Good Bye!</p>
No change and of course not! Our engine is namespaced, remember? Instead, I moved the template to parent_app/app/views/my_engine/posts/index.html.erb. Now visiting /my_engine/posts in the parent application showed “Good Bye!” That’s better. Next I decided to test out the engine’s helpers. I added a method to the Post helper inside the engine.
1
2
3
4
5
6
7
8
9
# my_engine/app/helpers/my_engine/posts_helper.rb
 
module MyEngine
  module PostsHelper
    def test
      raw("<p>hello world</p>")
    end
  end
end
I then changed the parent application’s view template to use the helper.
1
2
3
4
# parent_app/app/views/posts/index.html.erb
 
<p>Good Bye!</p>
<%= test %>
Visiting the page resulted in the words “Good Bye!” and “hello world.” Therefore, the engine’s helper methods were directly exposed to the parent application, allowing the parent to use them. To be honest, I did not expect this to work. There is a section in the Rails comments about sharing an isolated engine’s helpers with the parent application by using helper MyEngine::Engine.helpers in the application controller of the parent. It states that in doing so “[the parent application] will include all of the helpers from engine’s directory.” Perhaps this is a bug in the release candidates of Rails 3.1? Maybe my interpretation of the instructions is way off? I’m not sure. If this does change by the time you use it, and you can’t access the engine’s helpers, I suggest trying the method described.

Summary

It seems as though mountable engines are best suited as complete applications in themselves which run along side a parent application. The engine routes, controllers, models, helpers, etc. are namespaced and bundled into the mounted route within the parent application, thus avoiding namespace conflicts. If I’m way off in my assessment or there are other things which I have missed, drop me a line and I’ll add them!

 

Rails 3.1 Engines – Mountable or Full? – Part 1

Rails 3.1 Engines – Mountable or Full? – Part 1

I decided to create my first rails engine about a week or so ago.  I figured this was a great way to learn Rails 3.1 and the new engine generator; however, I quickly ran into a problem.  Do I want a mountable or full engine?  What’s the difference anyway?  At the time, a quick google search showed that not many people really knew. The Rails code comments are great, but after reading them, I was still a bit confused.  For those of you out there in the same boat, here’s my attempt at highlighting some of the differences.

Full Engines

Engine Details

To generate a full engine, run rails plugin new myengine --full on the console. This will generate the engine’s basic structure. The first thing I noticed was that the typical assets associated with a normal Rails application were not generated; application.js and application.css were not created. In fact, the application controller was completely omitted, alluding that perhaps a full engine is feared toward supplementing a parent application only. As far as routing goes, the engine’s route looked like this:
1
2
3
4
# my_engine/config/routes.rb
 
Rails.application.routes.draw do
end
… and the dummy application’s routes file looked like this:
1
2
3
4
5
# my_engine/test/dummy/config/routes.rb
 
Dummy::Application.routes.draw
  # route stuff
end
Another item that was missing from the basic application structure was the database folder. For engine configuration, a full engine is not namespaced, so the engine.rb file was essentially blank.
1
2
3
4
5
6
# my_engine/lib/my_engine/engine.rb
 
module MyEngine
  class Engine < Rails::Engine
  end
end
Now, the rails comments state that engines allow you to add a “subset of functionality to an existing Rails application.” Since the full engine is missing an application controller, it seems that its purpose is to plug into an existing application without namespacing to add functionality to the parent application. To test this theory, I generated a new application and referenced my engine in the parent application’s Gemfile.

Routing

Since the engine is not namespaced, the engine’s routes are incorporated into the parent application’s routes directly. To test this, I created a model within the engine called “Post”, along with the migration, controller, and helper to match. To create the migration, I also had to build the my_engine/db/migrate/ folder, which was not created when I generated the engine. Running rake routes within the parent application resulted in the following:
1
2
3
4
5
6
7
    posts GET    /posts(.:format)          {:action=>"index", :controller=>"posts"}
          POST   /posts(.:format)          {:action=>"create", :controller=>"posts"}
 new_post GET    /posts/new(.:format)      {:action=>"new", :controller=>"posts"}
edit_post GET    /posts/:id/edit(.:format) {:action=>"edit", :controller=>"posts"}
     post GET    /posts/:id(.:format)      {:action=>"show", :controller=>"posts"}
          PUT    /posts/:id(.:format)      {:action=>"update", :controller=>"posts"}
          DELETE /posts/:id(.:format)      {:action=>"destroy", :controller=>"posts"}
As you can see, the Post routes from the engine were included directly into the parent application. After running rake my_engine:install:migrations and rake db:migrate in the parent application, I was ready to test how the engine’s controllers and helpers would integrate. In my engine, I had a simple view template:
1
2
3
# my_engine/app/views/posts/index.html.erb
 
<p>Hi There!</p>
Of course, navigating to /posts in the parent application showed an almost blank page with the words “Hi There!” The controller actions and views from the engine were incorporated into the parent application. One helpful feature of engines is the fact that their controller methods and views can be overridden simply by placing similar files within the parent application. For example, I created a new view template for the Post index action within the parent application that looked like this:
1
2
3
# parent_app/app/views/posts/index.html.erb
 
<p>Good Bye!</p>
Now visiting /posts in the parent application shows “Good Bye!” That’s great, but what about the engine’s helpers? I tested that functionality by adding a method to the Post helper back inside the engine.
1
2
3
4
5
6
7
8
9
# my_engine/app/helpers/posts_helper.rb
 
module PostsHelper
 
  def test
    raw("<p>hello world</p>")
  end
 
end
I then changed the parent application’s view template to use the helper.
1
2
3
4
# parent_app/app/views/posts/index.html.erb
 
<p>Good Bye!</p>
<%= test %>
This time, visiting the page again in the parent application resulted in the words “Good Bye!” and “hello world.” Therefore, the engine’s helper methods were directly exposed to the parent application, allowing the parent to use them.

Summary

In summary, it seems as though full engines are best suited to augment a parent application. The engine routes, controllers, models, helpers, etc. are exposed to the parent application which allows for easy access, but could result in namespace conflicts. It looks like this post is getting a bit lengthy so I’ll stop it here and talk about mountable engines soon.

 

Windows Shell 脚本语法

windows Shell 脚本语法

windows Shell 脚本语法 扩展名是bat(在nt/2000/xp/2003下也可以是cmd)的文件就是批处理文件。 ==== 注 ======================================= .bat是dos下的批处理文件 .cmd是nt内核命令行环境的另一种批处理文件

从 更广义的角度来看,unix的shell脚本以及其它操作系统甚至应用程序中由外壳进行解释执行的文本,都具有与批处理文件十分相似的作用,而且同样是由 专用解释器以行为单位解释执行,这种文本形式更通用的称谓是脚本语言。所以从某个程度分析,batch, unix shell, awk, basic, perl 等脚本语言都是一样的,只不过应用的范围和解释的平台各有不同而已。甚至有些应用程序仍然沿用批处理这一称呼,而其内容和扩展名与dos的批处理却又完全 不同。

首先批处理文件是一个文本文件,这个文件的每一行都是一条DOS命令(大部分时候就好象我们在DOS提示符下执行的命令行一样),你可以使用DOS下的Edit或者Windows的记事本(notepad)等任何文本文件编辑工具创建和修改批处理文件。 ==== 注 ===================

批 处理文件中完全可以使用非dos命令,甚至可以使用不具有可执行特性的普通数据性文件,这缘于windows系统这个新型解释平台的涉入,使得批处理的应 用越来越”边缘化”。所以我们讨论的批处理应该限定在dos环境或者命令行环境中,否则很多观念和设定都需要做比较大的变动。

其 次,批处理文件是一种简单的程序,可以通过条件语句(if)和流程控制语句(goto)来控制命令运行的流程,在批处理中也可以使用循环语句(for)来 循环执行一条命令。当然,批处理文件的编程能力与C语言等编程语句比起来是十分有限的,也是十分不规范的。批处理的程序语句就是一条条的DOS命令(包括 内部命令和外部命令),而批处理的能力主要取决于你所使用的命令。 ==== 注 ==================

批 处理文件(batch file)也可以称之为批处理程序(batch program),这一点与编译型语言有所不同,就c语言来说,扩展名为c或者cpp的文件可以称之为c语言文件或者c语言源代码,但只有编译连接后的 exe文件才可以称之为c语言程序。因为批处理文件本身既具有文本的可读性,又具有程序的可执行性,这些称谓的界限是比较模糊的。

第 三,每个编写好的批处理文件都相当于一个DOS的外部命令,你可以把它所在的目录放到你的DOS搜索路径(path)中来使得它可以在任意位置运行。一个 良好的习惯是在硬盘上建立一个bat或者batch目录(例如C:\BATCH),然后将所有你编写的批处理文件放到该目录中,这样只要在path中设置 上c:\batch,你就可以在任意位置运行所有你编写的批处理程序。 ==== 注 ===== 纯以dos系统而言,可执 行程序大约可以细分为五类,依照执行优先级由高到低排列分别是:DOSKEY宏命令(预先驻留内存),COMMAND.COM中的内部命令(根据内存的环 境随时进驻内存),以com为扩展名的可执行程序(由command.com 直接载入内存),以exe位扩展名的可执行程序(由command.com 重定位后载入内存),以bat位扩展名的批处理程序(由command.com 解释分析,根据其内容按优先级顺序调用第2,3,4,5种可执行程序,分析一行,执行一行,文件本身不载入内存) ============ 第 四,在DOS和Win9x/Me系统下,C:盘根目录下的AUTOEXEC.BAT批处理文件是自动运行批处理文件,每次系统启动时会自动运行该文件,你 可以将系统每次启动时都要运行的命令放入该文件中,例如设置搜索路径,调入鼠标驱动和磁盘缓存,设置系统环境变量等。下面是一个运行于Windows 98下的autoexec.bat的示例: @ECHO OFF PATH C:\WINDOWS;C:\WINDOWS\COMMAND;C:\UCDOS;C:\DOSTools;
C:\SYSTOOLS;C:\WINTOOLS;C:\BATCH LH SMARTDRV.EXE /X LH DOSKEY.COM /insert LH CTMOUSE.EXE SET TEMP=D:\TEMP SET TMP=D:\TEMP ==== 注 ===== AUTOEXEC.BAT为DOS系统的自动运行批处理文件,由COMMAND.COM启动时解释执行; 而在Win9x环境中,不仅增加支持了 DOSSTART.BAT, WINSTART.BAT 等许多其它自动运行的批处理文件,对AUTOEXEC.BAT 也增加了 .DOS .W40 .BAK .OLD .PWS 等许多变体以适应复杂的环境和多变的需求。 ==== willsort 编注 ============= 以 下关于命令的分类,有很多值得推敲的地方。常用命令中的@本不是命令,而dir、copy等也很常用的命令却没有列入, 而特殊命令中所有命令对我来说都是常用命令。建议将批处理所引用的命令分为内部命令、外部命令、第三方程序三类。而内部命令和外部命令中别有一类是专用于 或常用于批处理中的命令可称之为”批处理命令”。 以下摘录MS-DOS 6.22 帮助文档中关于”批处理命令”的文字,当然,其中有些概念和定义已经有些落后了。 批处理命令 批处理文件或批处理程序是一个包含若干MS-DOS命令的正文文件,扩展名为.BAT。当在命令提示符下敲入批处理程序的名称时,MS-DOS成组执行此批处理程序中的命令。

任何在命令提示符下可使用的命令都可用在批处理程序中。此外,下面MS-DOS命令是专门在批处理程序中使用的。

常用命令 echo、@、call、pause、rem(小技巧:用::代替rem)是批处理文件最常用的几个命令,我们就从他们开始学起。 ==== 注 =========== 首先, @ 不是一个命令, 而是DOS 批处理的一个特殊标记符, 仅用于屏蔽命令行回显. 下面是DOS命令行或批处理中可能会见到的一些特殊标记符: CR(0D) 命令行结束符 Escape(1B) ANSI转义字符引导符 Space(20) 常用的参数界定符 Tab(09) ; = 不常用的参数界定符 + COPY命令文件连接符 * ? 文件通配符 “” 字符串界定符 | 命令管道符 < > >> 文件重定向符 @ 命令行回显屏蔽符 / 参数开关引导符 : 批处理标签引导符 % 批处理变量引导符 其次, :: 确实可以起到rem 的注释作用, 而且更简洁有效; 但有两点需要注意: 第一, 除了 :: 之外, 任何以 :开头的字符行, 在批处理中都被视作标号, 而直接忽略其后的所有内容, 只是为了与正常的标号相区别, 建议使用 goto 所无法识别的标号, 即在 :后紧跟一个非字母数字的一个特殊符号.

第 二, 与rem 不同的是, ::后的字符行在执行时不会回显, 无论是否用echo on打开命令行回显状态, 因为命令解释器不认为他是一个有效的命令行, 就此点来看, rem 在某些场合下将比 :: 更为适用; 另外, rem 可以用于 config.sys 文件中.

echo 表示显示此命令后的字符 echo off 表示在此语句后所有运行的命令都不显示命令行本身 @与echo off相象,但它是加在每个命令行的最前面,表示运行时不显示这一行的命令行(只能影响当前行)。 call 调用另一个批处理文件(如果不用call而直接调用别的批处理文件,那么执行完那个批处理文件后将无法返回当前文件并执行当前文件的后续命令)。 pause 运行此句会暂停批处理的执行并在屏幕上显示Press any key to continue…的提示,等待用户按任意键后继续 rem 表示此命令后的字符为解释行(注释),不执行,只是给自己今后参考用的(相当于程序中的注释)。 ==== 注 =====

此处的描述较为混乱, 不如直接引用个命令的命令行帮助更为条理

ECHO 当程序运行时,显示或隐藏批处理程序中的正文。也可用于允许或禁止命令的回显。 在运行批处理程序时,MS-DOS一般在屏幕上显示(回显)批处理程序中的命令。 使用ECHO命令可关闭此功能。 语法 ECHO [ON|OFF] 若要用echo命令显示一条命令,可用下述语法: echo [message] 参数 ON|OFF 指定是否允许命令的回显。若要显示当前的ECHO的设置,可使用不带参数的ECHO 命令。 message

指定让MS-DOS在屏幕上显示的正文。

CALL 从一个批处理程序中调用另一个批处理程序,而不会引起第一个批处理的中止。 语法 CALL [drive:][path]filename [batch-parameters] 参数 [drive:][path]filename 指定要调用的批处理程序的名字及其存放处。文件名必须用.BAT作扩展名。

batch-parameters

指定批处理程序所需的命令行信息。

PAUSE 暂停批处理程序的执行并显示一条消息,提示用户按任意键继续执行。只能在批处 理程序中使用该命令。 语法 PAUSE

REM 在批处理文件或CONFIG.SYS中加入注解。也可用REM命令来屏蔽命令(在CONFIG.SYS 中也可以用分号 ; 代替REM命令,但在批处理文件中则不能替代)。 语法 REM [string] 参数 string

指定要屏蔽的命令或要包含的注解。

例1:用edit编辑a.bat文件,输入下列内容后存盘为c:\a.bat,执行该批处理文件后可实现:将根目录中所有文件写入 a.txt中,启动UCDOS,进入WPS等功能。   批处理文件的内容为:         命令注释:     @echo off           不显示后续命令行及当前命令行     dir c:*.* >a.txt       将c盘文件列表写入a.txt     call c:\ucdos\ucdos.bat    调用ucdos     echo 你好            显示”你好”     pause              暂停,等待按键继续     rem 准备运行wps         注释:准备运行wps     cd ucdos            进入ucdos目录     wps               运行wps   批处理文件的参数 批处理文件还可以像C语言的函数一样使用参数(相当于DOS命令的命令行参数),这需要用到一个参数表示符”%“。 %[1-9]表示参数,参数是指在运行批处理文件时在文件名后加的以空格(或者Tab)分隔的字符串。变量可以从%0到%9,%0表示批处理命令本身,其它参数字符串用%1到%9顺序表示。 例2:C:根目录下有一批处理文件名为f.bat,内容为: @echo off format %1 如果执行C:>f a: 那么在执行f.bat时,%1就表示a:,这样format %1就相当于format a:,于是上面的命令运行时实际执行的是format a: 例3:C:根目录下一批处理文件名为t.bat,内容为: @echo off type %1 type %2 那么运行C:>t a.txt b.txt %1 : 表示a.txt %2 : 表示b.txt 于是上面的命令将顺序地显示a.txt和b.txt文件的内容。 ==== 注 =============== 参 数在批处理中也作为变量处理, 所以同样使用百分号作为引导符, 其后跟0-9中的一个数字构成参数引用符. 引用符和参数之间 (例如上文中的 %1 与 a: ) 的关系类似于变量指针与变量值的关系. 当我们要引用第十一个或更多个参数时, 就必须移动DOS 的参数起始指针. shift 命令正充当了这个移动指针的角色, 它将参数的起始指针移动到下一个参数, 类似C 语言中的指针操作. 图示如下: 初始状态, cmd 为命令名, 可以用 %0 引用 cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 经过1次shift后, cmd 将无法被引用 cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | | %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 经过2次shift后, arg1也被废弃, %9指向为空, 没有引用意义 cmd arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 ^ ^ ^ ^ ^ ^ ^ ^ ^ | | | | | | | | | %0 %1 %2 %3 %4 %5 %6 %7 %8

遗憾的是, win9x 和DOS下均不支持 shift 的逆操作. 只有在 nt 内核命令行环境下, shift 才支持 /n 参数, 可以以第一参数为基准返复移动起始指针.

特殊命令

if goto choice for是批处理文件中比较高级的命令,如果这几个你用得很熟练,你就是批处理文件的专家啦。

一、if 是条件语句,用来判断是否符合规定的条件,从而决定执行不同的命令。 有三种格式: 1、if [not] “参数” == “字符串” 待执行的命令 参数如果等于(not表示不等,下同)指定的字符串,则条件成立,运行命令,否则运行下一句。

例:if “%1”==“a” format a:

if 的命令行帮助中关于此点的描述为: IF [NOT] string1==string2 command 在此有以下几点需要注意: 1. 包含字符串的双引号不是语法所必须的, 而只是习惯上使用的一种”防空”字符 2. string1 未必是参数, 它也可以是环境变量, 循环变量以及其他字符串常量或变量

3. command 不是语法所必须的, string2 后跟一个空格就可以构成一个有效的命令行

2、if [not] exist [路径]文件名 待执行的命令 如果有指定的文件,则条件成立,运行命令,否则运行下一句。 如: if exist c:\config.sys type c:\config.sys 表示如果存在c:\config.sys文件,则显示它的内容。 ** 也可以使用以下的用法: if exist command device 是指DOS系统中已加载的设备, 在win98下通常有: AUX, PRN, CON, NUL COM1, COM2, COM3, COM4 LPT1, LPT2, LPT3, LPT4 XMSXXXX0, EMMXXXX0 A: B: C: …, CLOCK$, CONFIG$, DblBuff$, IFS$HLP$ 具体的内容会因硬软件环境的不同而略有差异, 使用这些设备名称时, 需要保证以下三点: 1. 该设备确实存在(由软件虚拟的设备除外) 2. 该设备驱动程序已加载(aux, prn等标准设备由系统缺省定义) 3. 该设备已准备好(主要是指a: b: …, com1…, lpt1…等) 可通过命令 mem/d | find “device” /i 来检阅你的系统中所加载的设备

另 外, 在DOS系统中, 设备也被认为是一种特殊的文件, 而文件也可以称作字符设备; 因为设备(device)与文件都是使用句柄(handle)来管理的, 句柄就是名字, 类似于文件名, 只不过句柄不是应用于磁盘管理, 而是应用于内存管理而已, 所谓设备加载也即指在内存中为其分配可引用的句柄.

3、if errorlevel <数字> 待执行的命令 很 多DOS程序在运行结束后会返回一个数字值用来表示程序运行的结果(或者状态),通过if errorlevel命令可以判断程序的返回值,根据不同的返回值来决定执行不同的命令(返回值必须按照从大到小的顺序排列)。如果返回值等于指定的数 字,则条件成立,运行命令,否则运行下一句。 如if errorlevel 2 goto x2 ==== 注 =========== 返回值从大到小的顺序排列不是必须的, 而只是执行命令为 goto 时的习惯用法, 当使用 set 作为执行命令时, 通常会从小到大顺序排列, 比如需将返回码置入环境变量, 就需使用以下的顺序形式: if errorlevel 1 set el=1 if errorlevel 2 set el=2 if errorlevel 3 set el=3 if errorlevel 4 set el=4 if errorlevel 5 set el=5 … 当然, 也可以使用以下循环来替代, 原理是一致的: for %%e in (1 2 3 4 5 6 7 8…) do if errorlevel %%e set el=%%e 更高效简洁的用法, 可以参考我写的另一篇关于获取 errorlevel 的文章 出 现此种现象的原因是, if errorlevel 比较返回码的判断条件并非等于, 而是大于等于. 由于 goto 的跳转特性, 由小到大排序会导致在较小的返回码处就跳出; 而由于 set命令的 “重复” 赋值特性, 由大到小排序会导致较小的返回码 “覆盖” 较大的返回码.

另外, 虽然 if errorlevel=<数字> command 也是有效的命令行, 但也只是 command.com 解释命令行时将 = 作为命令行切分符而忽略掉罢了

二、goto 批处理文件运行到这里将跳到goto所指定的标号(标号即label,标号用:后跟标准字符串来定义)处,goto语句一般与if配合使用,根据不同的条件来执行不同的命令组。 如: goto end :end echo this is the end 标号用”:字符串”来定义,标号所在行不被执行。 ==== willsort 编注 label 常被译为 “标签” , 但是这并不具有广泛的约定性. goto 与 : 联用可实现执行中途的跳转, 再结合 if 可实现执行过程的条件分支, 多个 if 即可实现命令的分组, 类似 C 中 switch case 结构或者 Basic 中的 select case 结构, 大规模且结构化的命令分组即可实现高级语言中的函数功能. 以下是批处理和C/Basic在语法结构上的对照: Batch C / Basic goto&: goto&: goto&:&if if{}&else{} / if&elseif&endif goto&:&if… switch&case / select case

goto&:&if&set&envar… function() / function(),sub()

三、choice 使用此命令可以让用户输入一个字符(用于选择),从而根据用户的选择返回不同的errorlevel,然后于if errorlevel配合,根据用户的选择运行不同的命令。 注意:choice命令为DOS或者Windows系统提供的外部命令,不同版本的choice命令语法会稍有不同,请用choice /?查看用法。 choice的命令语法(该语法为Windows 2003中choice命令的语法,其它版本的choice的命令语法与此大同小异): CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text] 描述: 该工具允许用户从选择列表选择一个项目并返回所选项目的索引。 参数列表: /C choices 指定要创建的选项列表。默认列表是 “YN”。 /N 在提示符中隐藏选项列表。提示前面的消息得到显示, 选项依旧处于启用状态。 /CS 允许选择分大小写的选项。在默认情况下,这个工具 是不分大小写的。 /T timeout 做出默认选择之前,暂停的秒数。可接受的值是从 0 到 9999。如果指定了 0,就不会有暂停,默认选项 会得到选择。 /D choice 在 nnnn 秒之后指定默认选项。字符必须在用 /C 选 项指定的一组选择中; 同时,必须用 /T 指定 nnnn。 /M text 指定提示之前要显示的消息。如果没有指定,工具只 显示提示。 /? 显示帮助消息。 注意: ERRORLEVEL 环境变量被设置为从选择集选择的键索引。列出的第一个选 择返回 1,第二个选择返回 2,等等。如果用户按的键不是有效的选择, 该工具会发出警告响声。如果该工具检测到错误状态,它会返回 255 的 ERRORLEVEL 值。如果用户按 Ctrl+Break 或 Ctrl+C 键,该工具会返回 0 的 ERRORLEVEL 值。在一个批程序中使用 ERRORLEVEL 参数时,将参数降 序排列。 示例: CHOICE /? CHOICE /C YNC /M “确认请按 Y,否请按 N,或者取消请按 C。” CHOICE /T 10 /C ync /CS /D y CHOICE /C ab /M “选项 1 请选择 a,选项 2 请选择 b。” CHOICE /C ab /N /M “选项 1 请选择 a,选项 2 请选择 b。” ==== willsort 编注 =============================== 我列出win98下choice的用法帮助, 已资区分 Waits for the user to choose one of a set of choices. 等待用户选择一组待选字符中的一个 CHOICE [/C[:]choices] [/N] [/S] [/T[:]c,nn] [text] /C[:]choices Specifies allowable keys. Default is YN 指定允许的按键(待选字符), 默认为YN /N Do not display choices and ? at end of prompt string. 不显示提示字符串中的问号和待选字符 /S Treat choice keys as case sensitive. 处理待选字符时大小写敏感 /T[:]c,nn Default choice to c after nn seconds 在 nn 秒后默认选择 c text Prompt string to display 要显示的提示字符串 ERRORLEVEL is set to offset of key user presses in choices. ERRORLEVEL 被设置为用户键入的字符在待选字符中的偏移值 如果我运行命令:CHOICE /C YNC /M “确认请按 Y,否请按 N,或者取消请按 C。” 屏幕上会显示: 确认请按 Y,否请按 N,或者取消请按 C。 [Y,N,C]?

例:test.bat的内容如下(注意,用if errorlevel判断返回值时,要按返回值从高到低排列): @echo off choice /C dme /M “defrag,mem,end” if errorlevel 3 goto end if errorlevel 2 goto mem if errorlevel 1 goto defrag :defrag c:\dos\defrag goto end :mem mem goto end :end echo good bye 此 批处理运行后,将显示”defrag,mem,end[D,M,E]?“ ,用户可选择d m e ,然后if语句根据用户的选择作出判断,d表示执行标号为defrag的程序段,m表示执行标号为mem的程序段,e表示执行标号为end的程序段,每个 程序段最后都以goto end将程序跳到end标号处,然后程序将显示good bye,批处理运行结束。 四、for 循环命令,只要条件符合,它将多次执行同一命令。 语法: 对一组文件中的每一个文件执行某个特定命令。 FOR %%variable IN (set) DO command [command-parameters] %%variable 指定一个单一字母可替换的参数。 (set) 指定一个或一组文件。可以使用通配符。 command 指定对每个文件执行的命令。 command-parameters 为特定命令指定参数或命令行开关。 例如一个批处理文件中有一行: for %%c in (.bat .txt) do type %%c 则该命令行会显示当前目录下所有以bat和txt为扩展名的文件的内容。 ==== willsort 编注 ===================================================== 需要指出的是, 当()中的字符串并非单个或多个文件名时, 它将单纯被当作字符串替换, 这个特性再加上()中可以嵌入多个字符串的特性, 很明显 for 可以被看作一种遍历型循环.

当然, 在 nt/2000/xp/2003 系列的命令行环境中, for 被赋予了更多的特性, 使之可以分析命令输出或者文件中的字符串, 也有很多开关被用于扩展了文件替换功能.

批处理示例 1. IF-EXIST 1) 首先用记事本在C:\建立一个test1.bat批处理文件,文件内容如下: @echo off IF EXIST \AUTOEXEC.BAT TYPE \AUTOEXEC.BAT IF NOT EXIST \AUTOEXEC.BAT ECHO \AUTOEXEC.BAT does not exist 然后运行它: C:>TEST1.BAT 如果C:\存在AUTOEXEC.BAT文件,那么它的内容就会被显示出来,如果不存在,批处理就会提示你该文件不存在。 2) 接着再建立一个test2.bat文件,内容如下: @ECHO OFF IF EXIST \%1 TYPE \%1 IF NOT EXIST \%1 ECHO \%1 does not exist 执行: C:>TEST2 AUTOEXEC.BAT 该命令运行结果同上。 说明: (1) IF EXIST 是用来测试文件是否存在的,格式为 IF EXIST [路径+文件名] 命令 (2) test2.bat文件中的%1是参数,DOS允许传递9个批参数信息给批处理文件,分别为%1~%9(%0表示test2命令本身) ,这有点象编程中的实参和形参的关系,%1是形参,AUTOEXEC.BAT是实参。 ==== willsort 编注 =====================================================

DOS没有 “允许传递9个批参数信息” 的限制, 参数的个数只会受到命令行长度和所调用命令处理能力的限制. 但是, 我们在批处理程序中, 在同一时刻只能同时引用10个参数, 因为 DOS只给出了 %0~%9这十个参数引用符.

3) 更进一步的,建立一个名为TEST3.BAT的文件,内容如下: @echo off IF “%1” == “A” ECHO XIAO IF “%2” == “B” ECHO TIAN IF “%3” == “C” ECHO XIN 如果运行: C:>TEST3 A B C 屏幕上会显示: XIAO TIAN XIN 如果运行: C:>TEST3 A B 屏幕上会显示 XIAO TIAN 在这个命令执行过程中,DOS会将一个空字符串指定给参数%3。 2、IF-ERRORLEVEL 建立TEST4.BAT,内容如下: @ECHO OFF XCOPY C:\AUTOEXEC.BAT D:\ IF ERRORLEVEL 1 ECHO 文件拷贝失败 IF ERRORLEVEL 0 ECHO 成功拷贝文件 然后执行文件: C:>TEST4 如果文件拷贝成功,屏幕就会显示”成功拷贝文件”,否则就会显示”文件拷贝失败”。 IF ERRORLEVEL 是用来测试它的上一个DOS命令的返回值的,注意只是上一个命令的返回值,而且返回值必须依照从大到小次序顺序判断。 因此下面的批处理文件是错误的: @ECHO OFF XCOPY C:\AUTOEXEC.BAT D:\ IF ERRORLEVEL 0 ECHO 成功拷贝文件 IF ERRORLEVEL 1 ECHO 未找到拷贝文件 IF ERRORLEVEL 2 ECHO 用户通过ctrl-c中止拷贝操作 IF ERRORLEVEL 3 ECHO 预置错误阻止文件拷贝操作 IF ERRORLEVEL 4 ECHO 拷贝过程中写盘错误 无论拷贝是否成功,后面的: 未找到拷贝文件 用户通过ctrl-c中止拷贝操作 预置错误阻止文件拷贝操作 拷贝过程中写盘错误 都将显示出来。 以下就是几个常用命令的返回值及其代表的意义: backup 0 备份成功 1 未找到备份文件 2 文件共享冲突阻止备份完成 3 用户用ctrl-c中止备份 4 由于致命的错误使备份操作中止 diskcomp 0 盘比较相同 1 盘比较不同 2 用户通过ctrl-c中止比较操作 3 由于致命的错误使比较操作中止 4 预置错误中止比较 diskcopy 0 盘拷贝操作成功 1 非致命盘读/写错 2 用户通过ctrl-c结束拷贝操作 3 因致命的处理错误使盘拷贝中止 4 预置错误阻止拷贝操作 format 0 格式化成功 3 用户通过ctrl-c中止格式化处理 4 因致命的处理错误使格式化中止 5 在提示”proceed with format(y/n)?“下用户键入n结束 xcopy 0 成功拷贝文件 1 未找到拷贝文件 2 用户通过ctrl-c中止拷贝操作 4 预置错误阻止文件拷贝操作 5 拷贝过程中写盘错误 chkdsk 0 未找到错误 255 找到一个或多个错误 choice 0 用户按下ctrl+c/break 1 用户按下第一个键 255 检测到命令行中的错误条件 其它 用户按下的有效字符在列表中的位置 defrag 0 碎片压缩成功 1 出现内部错误 2 磁盘上没有空簇。要运行DEFRAG,至少要有一个空簇 3 用户用Ctrl+C退出了DEFRAG 4 出现一般性错误 5 DEFRAG在读簇时遇到错误 6 DEFRAG在写簇时遇到错误 7 分配空间有错 8 内存错 9 没有足够空间来压缩磁盘碎片 deltree 0 成功地删除一个目录 diskcomp 0 两盘相同 1 发现不同 2 按CTRL+C 终止了比较 3 出现严重错误 4 出现初始化错误 find 0 查找成功且至少找到了一个匹配的字符串 1 查找成功但没找到匹配的字符串 2 查找中出现了错误 keyb 0 键盘定义文件装入成功 1 使用了非法的键盘代码,字符集或语法 2 键盘定义文件坏或未找到 4 键盘、监视器通讯时出错 5 要求的字符集未准备好 move 0 成功地移动了指定的文件 1 发生了错误 msav /N 86 检查到了病毒 replace 0 REPLACE成功地替换或加入了文件 1 MS-DOS版本和REPLACE不兼容 2 REPLACE找不到源文件 3 REPLACE找不到源路径或目标路径 5 不能存取要替换的文件 8 内存不够无法执行REPLACE 11 命令行句法错误 restore 0 RESTORE成功地恢复了文件 1 RESTORE找不到要恢复的文件 3 用户按CTRL+C终止恢复过程 4 RESTORE因错误而终止 scandisk 0 ScanDisk在它检查的驱动器上未检测到任何错误 1 由于命令行的语法不对,不能运行ScanDisk 2 由于内存用尽或发生内部错误,ScanDisk意外终止 3 用户让ScanDisk中途退出 4 进行盘面扫描时,用户决定提前退出 254 ScanDisk找到磁盘故障并已全部校正 255 ScanDisk找到磁盘故障,但未能全部校正 setver 0 SETVER成功地完成了任务 1 用户指定了一个无效的命令开关 2 用户指定了一个非法的文件名 3 没有足够的系统内存来运行命令 4 用户指定了一个非法的版本号格式 5 SETVER在版本表中未找到指定的项 6 SETVER未找到SETVER.EXE文件 7 用户指定了一个非法的驱动器 8 用户指定了太多的命令行参数 9 SETVER检测到丢失了命令行参数 10 在读SETVER.EXE文件时,SETVER检测到发生错误 11 SETVER.EXE文件损坏 12 指定的SETVER.EXE文件不支持版本表 13 版本表中没有足够的空间存放新的项

14 在写SETVER.EXE文件时SETVER检测到发生错误

3、IF STRING1 == STRING2 建立TEST5.BAT,文件内容如下: @echo off IF “%1” == “A” FORMAT A: 执行: C:>TEST5 A 屏幕上就出现是否将A:盘格式化的内容。 注意:为了防止参数为空的情况,一般会将字符串用双引号(或者其它符号,注意不能使用保留符号)括起来。 如:if [%1]==[A] 或者 if %1==A 5、GOTO 建立TEST6.BAT,文件内容如下: @ECHO OFF IF EXIST C:\AUTOEXEC.BAT GOTO COPY GOTO DONE :COPY COPY C:\AUTOEXEC.BAT D:\ :DONE 注意: (1) 标号前是ASCII字符的冒号”:“,冒号与标号之间不能有空格。 (2) 标号的命名规则与文件名的命名规则相同。 (3) DOS支持最长八位字符的标号,当无法区别两个标号时,将跳转至最近的一个标号。 ==== willsort 编注 ===================================================== 1)标号也称作标签(label) 2)标签不能以大多数的非字母数字字符开始, 而文件名中则可以使用很多

3)当无法区别两个标签时, 将跳转至位置最靠前的标签

6、FOR 建立C:\TEST7.BAT,文件内容如下: @ECHO OFF FOR %%C IN (.BAT .TXT *.SYS) DO TYPE %%C 运行: C:>TEST7 执行以后,屏幕上会将C:盘根目录下所有以BAT、TXT、SYS为扩展名的文件内容显示出来(不包括隐藏文件)。

免费的持续集成测试服务 –saberma

免费的持续集成测试服务 —saberma

ShopQi 大部分的功能都是被自动化测试覆盖的,每次代码提交之前如果都要在本地把所有测试跑一遍所花费的时间也不少。所以我们需要有一个服务器,代码提交后自动触发运行所有测试用例。

排除自建服务器这条路子,就只能在网上寻找了,优先考虑免费的

当时(几个月前)找的时候,travis-ci还没有出来,其他收费的持续集成也不太满意。 在一次偶然的机会,看到github上某个项目的README中显示了一个building status的图标,才发现了 travis-ci

从6月初使用到现在, travis-ci 的功能已经非常完善稳定,因此推荐给大家试用一下

travis-ci

A distributed build system for the open source community. 专为开源社区打造的分布式编译系统,也就是持续集成测试了。

它有以下特点:

  1. 免费,虽然是免费,但比收费的还要简单好用!
  2. 支持多语言: 支持Clojure Erlang Javascript(Node.js) PHP Ruby,我只试用了Ruby
  3. 支持多环境: 例如同时测试项目在 ruby1.8.6, 1.9.2, 1.9.3, jruby等的运行情况,支持多数据库mysql, postgres等
  4. 支持浏览器headless测试: 结合Xvfb可以跑集成测试了
  5. 非侵入式,只需要一个.travis.yml,就可以了,项目不用做过多的改动

配置.travis.yml

项目的根目录要加入 .travis.yml 文件 在里面指定rvm使用的ruby版本,指定bundler的运行参数等等

可以参考 .travis.yml

使用

要有一个 github 帐号,在 travis-ci网站 使用该帐号登录 在 profile 选中您要使用的 项目 就可以了

以后向github提交代码时,travis-ci就会自动跑测试了,测试結果会发送到邮箱

Rails Object Relationships and JSON Rendering

Rails Object Relationships and JSON Rendering

class ModelA < ActiveRecord::Base   belongs_to :ModelB

  …

class ModelB < ActiveRecord::Base   has_many :ModelA

When calling the show action of the ModelA controller the returned JSON should show all ObjectAs that are children of the ObjectB of which the ObjectA in question is a child of.

By default you’ll only get the JSON that represents modelb in your example above. But, you can tell Rails to include the other related objects as well:

def export   @export_data = ModelA.find(params[:id])   respond_to do |format|     format.html     format.json { render :json => @export_data.to_json(:include => :modelb) }   end end

You can even tell it to exclude certain fields if you don’t want to see them in the export:

render :json => @export_data.to_json(:include => { :modelb => { :except => [:created_at, updated_at]}})

Or, include only certain fields:

render :json => @export_data.to_json(:include => { :modelb => { :only => :name }})

And you can nest those as deeply as you need (let’s say that ModelB also has_many ModelC):

render :json => @export_data.to_json(:include => { :modelb => { :include => :modelc }})

Ubuntu 下利用ndiswrapper安装无线网卡驱动

ubuntu 下利用ndiswrapper安装无线网卡驱动

首先 安装 ndiswrapper ubuntu下也就是 ndisgtk   (用于安装无线网卡驱动) sudo apt-get install ndisgtk 安装好了之后,找到你的无线网卡在windows下的驱动文件(含有.inf的目录)(可以从网上下载也可以从驱动盘中获得),将该目录中的文件拷到主目录的新建文件夹中, 执行 sudo ndiswrapper -i yourname.inf     //yourname是你驱动inf的文件名称 安装以后会在  /etc/ndiswrapper/  下面建立一个相应的目录youname, 到该目录下(cd /etc/ndiswrapper)执行  sudo ndiswrapper -l   //查看驱动安装ok了没 显示driver installed 写入配置文件: sudo ndiswrapper -m           (让ndiswrapper在启动时自动加载, 无线网卡会在系统启动初始化hotplug subsysytem时装载(这时卡上的电源灯才会亮) ) modprobe ndiswrapper        (让linux加载ndiswrapper module) 这样就可以配置无线网卡了,在SSID中输入无线路由名,在“无线安全性”中选择“WPA及WPA2个人”,然后输入密码即可。 配置好后重启下无线网络即连接成功。 终端中的步骤: sudo apt-get install ndisgtk # sudo ndiswrapper -i net8192u.inf cd /etc/ndiswrapper/ sudo ndiswrapper -l sudo ndiswrapper -m sudo ndiswrapper -mi   \保证重启之后不再设置 sudo modprobe ndiswrapper 最后设置无线网络连接。