没有人拥有一切,所以享受你所拥有的

发布新日志

  • 图片的格式

    2010-02-11 10:46:18

    一、BMP图像文件格式

    BMP是一种与硬件设备无关的图像文件格式,使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BblP文件所占用的空间很大。BMP文件的图像深度可选lbit、4bit、8bit及24bit。BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。

      由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。

      典型的BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息。

    二、 PCX图像文件格式

      PCX这种图像文件的形成是有一个发展过程的。最先的PCX雏形是出现在ZSOFT公司推出的名叫PC PAINBRUSH的用于绘画的商业软件包中。以后,微软公司将其移植到 Windows环境中,成为Windows系统中一个子功能。先在微软的Windows3.1中广泛应用,随着Windows的流行、升级,加之其强大的图像处理能力,使PCX同GIF、TIFF、BMP图像文件格式一起,被越来越多的图形图像软件工具所支持,也越来越得到人们的重视。

      PCX是最早支持彩色图像的一种文件格式,现在最高可以支持256种彩色,如图4-25所示,显示256色的彩色图像。PCX设计者很有眼光地超前引入了彩色图像文件格式,使之成为现在非常流行的图像文件格式。

    PCX图像文件由文件头和实际图像数据构成。文件头由128字节组成,描述版本信息和图像显示设备的横向、纵向分辨率,以及调色板等信息:在实际图像数据中,表示图像数据类型和彩色类型。PCX图像文件中的数据都是用PCXREL技术压缩后的图像数据。

      PCX是PC机画笔的图像文件格式。PCX的图像深度可选为l、4、8bit。由于这种文件格式出现较早,它不支持真彩色。PCX文件采用RLE行程编码,文件体中存放的是压缩后的图像数据。因此,将采集到的图像数据写成PCX文件格式时,要对其进行RLE编码:而读取一个PCX文件时首先要对其进行RLE解码,才能进一步显示和处理。

    三、TIFF图像文件格式

     TIFF(TaglmageFileFormat)图像文件是由Aldus和Microsoft公司为桌上出版系统研制开发的一种较为通用的图像文件格式。TIFF格式灵活易变,它又定义了四类不同的格式:TIFF-B适用于二值图像:TIFF-G适用于黑白灰度图像;TIFF-P适用于带调色板的彩色图像:TIFF-R适用于RGB真彩图像。

      TIFF支持多种编码方法,其中包括RGB无压缩、RLE压缩及JPEG压缩等。

      TIFF是现存图像文件格式中最复杂的一种,它具有扩展性、方便性、可改性,可以提供给IBMPC等环境中运行、图像编辑程序。

      TIFF图像文件由三个数据结构组成,分别为文件头、一个或多个称为IFD的包含标记指针的目录以及数据本身。

      TIFF图像文件中的第一个数据结构称为图像文件头或IFH。这个结构是一个TIFF文件中唯一的、有固定位置的部分;IFD图像文件目录是一个字节长度可变的信息块,Tag标记是TIFF文件的核心部分,在图像文件目录中定义了要用的所有图像参数,目录中的每一目录条目就包含图像的一个参数。

    四、 GIF文件格式

      GIF(Graphics Interchange Format)的原义是“图像互换格式”,是CompuServe公司在 1987年开发的图像文件格式。GIF文件的数据,是一种基于LZW算法的连续色调的无损压缩格式。其压缩率一般在50%左右,它不属于任何应用程序。目前几乎所有相关软件都支持它,公共领域有大量的软件在使用GIF图像文件。

      GIF图像文件的数据是经过压缩的,而且是采用了可变长度等压缩算法。所以GIF的图像深度从lbit到8bit,也即GIF最多支持256种色彩的图像。GIF格式的另一个特点是其在一个GIF文件中可以存多幅彩色图像,如果把存于一个文件中的多幅图像数据逐幅读出并显示到屏幕上,就可构成一种最简单的动画。

      GIF解码较快,因为采用隔行存放的GIF图像,在边解码边显示的时候可分成四遍扫描。第一遍扫描虽然只显示了整个图像的八分之一,第二遍的扫描后也只显示了1/4,但这已经把整幅图像的概貌显示出来了。在显示GIF图像时,隔行存放的图像会给您感觉到它的显示速度似乎要比其他图像快一些,这是隔行存放的优点。

    五、JPEG文件格式

      JPEG是Joint Photographic Experts Group(联合图像专家组)的缩写,文件后辍名为“.jpg”或“.jpeg”,是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且 JPEG是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。比如可以把1.37Mb的BMP位图文件压缩至20.3KB。当然也可以在图像质量和文件尺寸之间找到平衡点。JPEG格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。

      JPEG格式是目前网络上最流行的图像格式,是可以把文件压缩到最小的格式,在 Photoshop软件中以JPEG格式储存时,提供11级压缩级别,以0—10级表示。其中0级压缩比最高,图像品质最差。即使采用细节几乎无损的10级质量保存时,压缩比也可达 5:1。以BMP格式保存时得到4.28MB图像文件,在采用JPG格式保存时,其文件仅为178KB,压缩比达到24:1。经过多次比较,采用第8级压缩为存储空间与图像质量兼得的最佳比例。

      JPEG格式的应用非常广泛,特别是在网络和光盘读物上,都能找到它的身影。目前各类浏览器均支持JPEG这种图像格式,因为JPEG格式的文件尺寸较小,下载速度快。

      JPEG2000作为JPEG的升级版,其压缩率比JPEG高约30%左右,同时支持有损和无损压缩。JPEG2000格式有一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,不断提高图像质量,让图像由朦胧到清晰显示。此外,JPEG2000还支持所谓的“感兴趣区域”特性,可以任意指定影像上感兴趣区域的压缩质量,还可以选择指定的部分先解压缩。

      JPEG2000和JPEG相比优势明显,且向下兼容,因此可取代传统的JPEG格式。JPEG2000即可应用于传统的JPEG市场,如扫描仪、数码相机等,又可应用于新兴领域,如网路传输、无线通讯等等。

    六、TGA格式

      TGA格式(Tagged Graphics)是由美国Truevision公司为其显示卡开发的一种图像文件格式,文件后缀为“.tga”,已被国际上的图形、图像工业所接受。TGA的结构比较简单,属于一种图形、图像数据的通用格式,在多媒体领域有很大影响,是计算机生成图像向电视转换的一种首选格式。

    TGA图像格式最大的特点是可以做出不规则形状的图形、图像文件,一般图形、图像文件都为四方形,若需要有圆形、菱形甚至是缕空的图像文件时,TGA可就派上用场了! TGA格式支持压缩,使用不失真的压缩算法。

    七、EXIF格式

      EXIF的格式是1994年富士公司提倡的数码相机图像文件格式,其实与JPEG格式相同,区别是除保存图像数据外,还能够存储摄影日期、使用光圈、快门、闪光灯数据等曝光资料和附带信息以及小尺寸图像。

    八、 FPX图像文件格式

      FPX图像文件格式(扩展名为fpx)是由柯达、微软、HP及Live PictureInc联合研制,并于1996年6月正式发表,FPX是一个拥有多重分辩率的影像格式,即影像被储存成一系列高低不同的分辩率,这种格式的好处是当影像被放大时仍可维持影像的质素,另外,当修饰FPX影像时,只会处理被修饰的部分,不会把整幅影像一并处理,从而减小处理器及记忆体的负担,使影像处理时间减少。

    九、SVG格式

      SVG是可缩放的矢量图形格式。它是一种开放标准的矢量图形语言,可任意放大图形显示,边缘异常清晰,文字在SVG图像中保留可编辑和可搜寻的状态,没有字体的限制,生成的文件很小,下载很快,十分适合用于设计高分辨率的Web图形页面。

    十、PSD文件格式

      这是Photoshop图像处理软件的专用文件格式,文件扩展名是.psd,可以支持图层、通道、蒙板和不同色彩模式的各种图像特征,是一种非压缩的原始文件保存格式。扫描仪不能直接生成该种格式的文件。PSD文件有时容量会很大,但由于可以保留所有原始信息,在图像处理中对于尚未制作完成的图像,选用PSD格式保存是最佳的选择。

    十一、CDR文件格式

      CDR格式是著名绘图软件CorelDRAW的专用图形文件格式。由于CorelDRAW是矢量图形绘制软件,所以CDR可以记录文件的属性、位置和分页等。但它在兼容度上比较差,所有CorelDraw应用程序中均能够使用,但其他图像编辑软件打不开此类文件。 十二、PCD文件格式

      PCD是Kodak PhotoCD的缩写,文件扩展名是.pod,是Kodak开发的一种Photo CD文件格式,其他软件系统只能对其进行读取。该格式使用YCC色彩模式定义图像中的色彩。YCC和CIE色彩空间包含比显示器和打印设备的RGB色和CMYK色多得多的色彩。PhotoCD图像大多具有非常高的质量。

    十三、DXF文件格式

      DXF是Drawing Exchange Format的缩写,扩展名是.dxf,是AutoCAD中的图形文件格式,它以ASCII方式储存图形,在表现图形的大小方面十分精确,可被CorelDraw和3DS等大型软件调用编辑。

    十四、UFO文件格式

      它是著名图像编辑软件Ulead Photolmapct的专用图像格式,能够完整地记录所有 Photolmapct处理过的图像属性。值得一提的是,UFO文件以对象来代替图层记录图像信息。

    十五、EPS文件格式

      EPS是Encapsulated PostScript的缩写,是跨平台的标准格式,扩展名在PC平台上是.eps,在Macintosh平台上是.epsf,主要用于矢量图像和光栅图像的存储。EPS格式采用 PostScript语言进行描述,并且可以保存其他一些类型信息,例如多色调曲线、Alpha通道、分色、剪辑路径、挂网信息和色调曲线等,因此EPS格式常用于印刷或打印输出。Photoshop中的多个EPS格式选项可以实现印刷打印的综合控制,在某些情况下甚至优于TIFF格式。

    十六、PNG图像文件格式

      PNG(Portable Networf Graphics)的原名称为“可移植性网络图像”,是网上接受的最新图像文件格式。PNG能够提供长度比GIF小30%的无损压缩图像文件。它同时提供24位和48位真彩色图像支持以及其他诸多技术性支持。由于PNG非常新,所以目前并不是所有的程序都可以用它来存储图像文件,但Photoshop可以处理PNG图像文件,也可以用PNG图像文件格式存储

  • 性能测试(并发负载压力)测试分析-简要篇

    2010-02-09 22:45:36


    注释:网上转来的。。。。。


    分析原则:
    • 具体问题具体分析(这是由于不同的应用系统,不同的测试目的,不同的性能关注点)

    • 查找瓶颈时按以下顺序,由易到难。

    服务器硬件瓶颈-〉网络瓶颈(对局域网,可以不考虑)-〉服务器操作系统瓶颈(参数配置)-〉中间件瓶颈(参数配置,数据库,web服务器等)-〉应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等)


    注:以上过程并不是每个分析中都需要的,要根据测试目的和要求来确定分析的深度。对一些要求低的,我们分析到应用系统在将来大的负载压力(并发用户数、数据量)下,系统的硬件瓶颈在哪儿就够了。

    • 分段排除法 很有效

    分析的信息来源:

    •1 根据场景运行过程中的错误提示信息

    •2 根据测试结果收集到的监控指标数据

    一.错误提示分析

    分析实例:

    1 •Error: Failed to connect to server “10.10.10.30:8080″: [10060] Connection

    •Error: timed out Error: Server “10.10.10.30″ has shut down the connection prematurely

    分析:

    •A、应用服务死掉。

    (小用户时:程序上的问题。程序上处理数据库的问题)

    •B、应用服务没有死

    (应用服务参数设置问题)

    例:在许多客户端连接Weblogic应用服务器被拒绝,而在服务器端没有错误显示,则有可能是Weblogic中的server元素的AcceptBacklog属性值设得过低。如果连接时收到connection refused消息,说明应提高该值,每次增加25%

    •C、数据库的连接

    (1、在应用服务的性能参数可能太小了 2、数据库启动的最大连接数(跟硬件的内存有关))

    2 Error: Page download timeout (120 seconds) has expired

    分析:可能是以下原因造成

    •A、应用服务参数设置太大导致服务器的瓶颈

    •B、页面中图片太多

    •C、在程序处理表的时候检查字段太大多

    二.监控指标数据分析

    1.最大并发用户数:

    应用系统在当前环境(硬件环境、网络环境、软件环境(参数配置))下能承受的最大并发用户数。

    在方案运行中,如果出现了大于3个用户的业务操作失败,或出现了服务器shutdown的情况,则说明在当前环境下,系统承受不了当前并发用户的负载压力,那么最大并发用户数就是前一个没有出现这种现象的并发用户数。

    如果测得的最大并发用户数到达了性能要求,且各服务器资源情况良好,业务操作响应时间也达到了用户要求,那么OK。否则,再根据各服务器的资源情况和业务操作响应时间进一步分析原因所在。

    2.业务操作响应时间:

    • 分析方案运行情况应从平均事务响应时间图和事务性能摘要图开始。使用“事务性能摘要”图,可以确定在方案执行期间响应时间过长的事务。

    • 细分事务并分析每个页面组件的性能。查看过长的事务响应时间是由哪些页面组件引起的?问题是否与网络或服务器有关?

    • 如果服务器耗时过长,请使用相应的服务器图确定有问题的服务器度量并查明服务器性能下降的原因。如果网络耗时过长,请使用“网络监视器”图确定导致性能瓶颈的网络问题

    3.服务器资源监控指标:

    内存:

    1 UNIX资源监控中指标内存页交换速率(Paging rate),如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。也可能是内存访问命中率低。

    2 Windows资源监控中,如果Process\Private Bytes计数器和Process\Working Set计数器的值在长时间内持续升高,同时Memory\Available bytes计数器的值持续降低,则很可能存在内存泄漏。

    内存资源成为系统性能的瓶颈的征兆:

    很高的换页率(high pageout rate);

    进程进入不活动状态;

    交换区所有磁盘的活动次数可高;

    可高的全局系统CPU利用率; 

    内存不够出错(out of memory errors)

    处理器:

    1 UNIX资源监控(Windows操作系统同理)中指标CPU占用率(CPU utilization),如果该值持续超过95%,表明瓶颈是CPU。可以考虑增加一个处理器或换一个更快的处理器。如果服务器专用于SQL Server,可接受的最大上限是80-85% 

    合理使用的范围在60%至70%。

    2 Windows资源监控中,如果System\Processor Queue Length大于2,而处理器利用率(Processor Time)一直很低,则存在着处理器阻塞。

    CPU资源成为系统性能的瓶颈的征兆: 

    很慢的响应时间(slow response time) 

    CPU空闲时间为零(zero percent idle CPU) 

    过高的用户占用CPU时间(high percent user CPU) 

    过高的系统占用CPU时间(high percent system CPU) 

    长时间的有很长的运行进程队列(large run queue size sustained over time)

    磁盘I/O:

    1 UNIX资源监控(Windows操作系统同理)中指标磁盘交换率(Disk rate),如果该参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。

    2 Windows资源监控中,如果 Disk Time和Avg.Disk Queue Length的值很高,而Page Reads/sec页面读取操作速率很低,则可能存在磁盘瓶径。

    I/O资源成为系统性能的瓶颈的征兆 :

    过高的磁盘利用率(high disk utilization) 

    太长的磁盘等待队列(large disk queue length) 

    等待磁盘I/O的时间所占的百分率太高(large percentage of time waiting for disk I/O) 

    太高的物理I/O速率:large physical I/O rate(not sufficient in itself) 

    过低的缓存命中率(low buffer cache hit ratio(not sufficient in itself)) 

    太长的运行进程队列,但CPU却空闲(large run queue with idle CPU)

    4.数据库服务器:

    SQL Server数据库:

    1 SQLServer资源监控中指标缓存点击率(Cache Hit Ratio),该值越高越好。如果持续低于80%,应考虑增加内存。

    2 如果Full Scans/sec(全表扫描/秒)计数器显示的值比1或2高,则应分析你的查询以确定是否确实需要全表扫描,以及SQL查询是否可以被优化。 

    3 Number of Deadlocks/sec(死锁的数量/秒):死锁对应用程序的可伸缩性非常有害,并且会导致恶劣的用户体验。该计数器的值必须为0。

    4 Lock Requests/sec(锁请求/秒),通过优化查询来减少读取次数,可以减少该计数器的值。

    Oracle数据库:

    1 如果自由内存接近于0而且库快存或数据字典快存的命中率小于0.90,那么需要增加SHARED_POOL_SIZE的大小。

    快存(共享SQL区)和数据字典快存的命中率: 

    select(sum(pins-reloads))/sum(pins) from v$librarycache; 

    select(sum(gets-getmisses))/sum(gets) from v$rowcache; 

    自由内存: select * from v$sgastat where name=’free memory’; 

    2 如果数据的缓存命中率小于0.90,那么需要加大DB_BLOCK_BUFFERS参数的值(单位:块)。

    缓冲区高速缓存命中率:

    select name,value from v$sysstat where name in (’db block gets’,

    ‘consistent gets’,'physical reads’) ;

    Hit Ratio = 1-(physical reads / ( db block gets + consistent gets))

    3 如果日志缓冲区申请的值较大,则应加大LOG_BUFFER参数的值。

    日志缓冲区的申请情况 :

    select name,value from v$sysstat where name = ‘redo log space requests’ ;

    4 如果内存排序命中率小于0.95,则应加大SORT_AREA_SIZE以避免磁盘排序 。

    内存排序命中率 :

    select round((100*b.value)/decode((a.value+b.value), 0, 1, (a.value+b.value)), 2)from v$sysstat a, v$sysstat b where a.name=’sorts (disk)’ and b.name=’sorts (memory)’

    注:上述SQL Server和Oracle数据库分析,只是一些简单、基本的分析,特别是Oracle数据库的分析和优化,是一门专门的技术,进一步的分析可查相关资料。

  • 上传文件测试点

    2009-10-30 14:31:43


    1 上传文件名测试,检查不符合文件名规范
    2 上传文件名类型测试,检查不同文件类型是否支持如:.rar,.mp3,avi等
    3 上传文件大小测试,检查不同文件规格大小如:0字节文件, 1kb, 200kb, 2mb, 20mb,2g等
    4 上传文件容错性测试:如检查覆盖同文件操作;
    5 上传文件异常情况测试:如硬盘空间不足
    6  上传文件速率性能测试:检查上传不同的文件在不同的网络环境响应速度,及系统资源占用
    7 上传文件安全性测试:如上传常见木马
    8 上传文件易用性测试:检查上传文件操作是否让用户易于学习和理解使用等
    9 上传文件特性测试:如果支持如断点续传等一些特性
    10 上传文件后,检查是否与源文件一致,包含目录设置等
    11 上传文件,是否能打开等
    列举一些常见的测试点,其实上传文件测试比较复杂,诚然也要看系统的应用,有效的选择测试用例
  • [论坛] QC 备份(转)

    2009-10-19 18:34:40

    目的:QC-A上面所有项目备份到QC-B上面能用。

    一:对QC-A数据库进行备份,备份所有的库。

    二:备份QC-A安装目录下的repository文件夹,复制一份就可以了。

    三:在QC-B上面安装好SQL QC程序。这里要注意,QC-B的程序安装路径一定要和QC-A一模一样。

    四:在QC-B上面安装好QC程序的时候,数据库里面已经有了2个库,qcsiteadmin_db和qcsiteadmin_db库,将这个2个库重命名。

    五:将第一步备份的repository文件覆盖QC-B安装路径下的repository文件夹。

    六:将QC-A上面数据库全部还原到QC-B上面去,里面有qcsiteadmin_db和qcsiteadmin_db库。

    七:用admin帐号和QC-A的管理密码登录QC-B的管理界面,将所有的项目激活(还原过来的项目都处于非激活状态)

    八:在QC-B的管理平台里面将所有项目的数据库连接地址改成QC-B的数据库。

    到这里从QC-A到QC-B的过程就算完成,可以用QC-A的帐号合和密码登录到QC-B上面去。

    转载别人的,但是按照这个过程操作了一边,但并没有成功

    而且步骤“四:在QC-B上面安装好QC程序的时候,数据库里面已经有了2个库,qcsiteadmin_db和qcsiteadmin_db库,将这个2个库重命名。”

    实际安装的时候QC-B上的数据库里有qcsiteadmin_db和qc的demo数据库(库名忘了),上面所说的“qcsiteadmin_db库”不知道是什么意思,还有就是不知道为什么要重命名~~~~~

    “五:将第一步备份的repository文件覆盖QC-B安装路径下的repository文件夹。” -----如果这样做的话,QC的站点管理就登陆不了(QC-B上安装好QC后是可以用安装时创建的站点管理员登陆的),尝试先不覆盖QC-B上的repository,而是先在QC-B上创建和QC-A相同的域和项目,再将在QC-A对应的项目数据库还原QC-B上,这样QC-B站点管理可以登陆,但项目不能添加用户,不知道是什么原因

    最后没有通过这种方法,换了个方法,直接在QC-A上的项目从站点管理中导出来(.qcp)文件,再导入到QC-B上,这样QC-B上就可以用这个项目了

  • 查询测试

    2009-09-30 12:21:16

     

     

    1 查询输入

    (1)分别对单条件进行精确查询

    (2)输入长度的检验,输入允许的最长值进行查询,是否支持

    (3)两个查询条件是否为2选1,来回选择是否出现页面错误

    (4)输入字符

    (5)输入特殊字符

    (6)输入数字

    (7)输入汉字

    (8)输入关系表达式 与、或、异或、非、等于

    (9)输入空格

    (10)条件中含有空格

    (11)输入超长字符

    (12)输入全角字符

    (13)输入单引号

    (14)输入单引号引起来的数据

    (15)输入双引号

    (16)输入双引号引起来的数据

    (17)如果支持模糊查询,输入部分查询条件

    (18)输入系统中不存在与之匹配的条件

    查询结果检查

    (1)查询结果按什么顺利排序

    (2)查询结果是否根据字段显示排序功能

    (3)查询结果是否有分页,如果有,每页最多包含多少记录

    (4)查询结果是否匹配

    (5)查询结果是否与数据库一致

    (6)查询结果是精确查询还是模糊查询

    UI验证

    (1)文字显示是否正确

    (2)页面是否有错别字

    (3)输入框大小、文字大小是否合适

    (4)页面是否美观

    (5)查询结果字段显示是否与需求一致

    性能方面

    (1)查询处理时间是否能接受

    (2)数据库中存在大数据量数据时,查询时间是否能接受

    (3)当多个用户同时查询时,输入相同或不同的查询条件系统响应是否及时。

  • 度量项目质量优劣的六个维度(转)

    2009-09-29 18:34:17

    本文主要从测试工作的角度,对几个测试相关的维度进行分析,说明它们是如何影响项目质量的。这6个维度是作者自己的总结,并非来自于教科书,仅供大家参考。这六个维度也只是和功能测试有关,至于系统的性能、可靠性、可用性如何度量,以后我们在别的文章里再做讨论。

      首先,我们要明确一个概念,就是“严重bug”。这6个维度,有很多都和严重bug有关。严重bug指的是项目中,严重性是1级和2级的bug。注意,并不是优先级,而是严重性。严重性1级是“block”,指程序无法正常运行或者是测试无法正常进行,随便点两下,就报错;2级是major,指功能的各种错误,总之是用户不可接受的错误。3级大多是文案或者是易用性的问题,用户可以接受少量这种类型的bug。

      好,下面开始讨论那六个维度,我会说明计算方法,以及它们的战略意义。

      1、严重bug数 / 测试用例数

      这个维度代表了一个项目的严重bug数量是否正常,让测试用例参与计算,是为了平衡规模不同的项目的数据。

      2、第三轮测试出现的严重bug数 / 严重bug总数

      目前我们的测试过程模型是“三轮测试”,三轮的目标分别是:发现bug、验证bug、稳定回归。如果在第三轮回归的时候,还出现大量严重bug,那肯定是不正常的,也会对质量构成巨大风险。这个数字应该要控制在一个很低的水平。

      3、被reopen的严重bug / 严重bug总数

      reopen指开发fix后,测试验证不通过,或者是已经close的bug又复发。这个维度也应该被控制在一个很低的水平,如果偏高,说明开发修复bug的效率偏低,代码不稳定,发布后出现bug的几率增加。

      4、第二轮测试用例执行通过率

      因为第二轮的目标就是修复bug,所以如果第二轮结束的时候,严重bug全部被修复,并且第三轮没有出现新的严重bug,那么可以说项目的质量是非常稳定的。这里判定第二轮用例通过与否的标准,就是看第二轮结束时,如果有严重bug没有关闭,那相关的测试用例就是failed。此外,3级bug如果没有关闭,除非有确定的用例与之对应,否则不会影响用例的通过率。

      5、测试工作量(人月) / 测试用例数

      这个维度代表投入的测试资源是否充足,这里的工作量,指的是从测试设计到测试执行的所有人月数。如果数字过低,说明测试资源紧张,无法保证测试质量;如果过高,说明有可能测试效率低,测试经理需要进行解释。

      6、严重bug平均关闭时间(天)

      bug 关闭时间,指bug从创建开始,到close为止,经过的时间,要精确到小数点后1位。只有状态是close的bug,才会计算关闭时间。平均关闭时间的计算方法也很简单,把所有closed严重bug求平均值即可。这个维度代表项目组解决bug的效率,如果时间太长,说明项目组对bug重视不够。

      其实要度量项目的质量,还有很多维度要考虑,比如需求文档、设计方案、代码等等,不过我们还是先在测试的范畴进行讨论,欢迎大家对这些维度提改进建议,或者提出新的维度。

  • LR 参数化取值

    2009-09-15 17:53:50

    1.
    select next row:unique
    update value on:each iteration

    a。Automatically allocate block size
    在给定的文件中参数值的数量以及给定的迭代数基础上,我们如何得知允许的最大用户数?
    参数值数量除以迭代次数,如果能整除,则结果就是最大用户数;如果不能整除,则结果取整后加1是最大用户数。

    b。Allocate XXX values for each users
    lr根据用户设定的XXX数值,顺序的将文件中参数值给予用户。比如设定了2,则文件表中第一第二个值就给予了用户a;第三第四个值就给予了用户b。

    2.
    select next row:unique
    update value on:each occurrence

    Allocate XXX values for each users(这个功能只提供具体的XXX值)
    lr根据用户设定的XXX数值,顺序的将参数表中的可取值给予用户。比如设定了2,则文件表中第一第二个值就给予了用户a;第三第四个值就给予了用户b。

    3.
    select next row:unique
    update value on:once

    这个选项意味着,lr给每个用户仅一个值,无论用户迭代多少次。

    4.
    select next row:sequence
    update value on:each iteration

    这个选项意味着,每次迭代时,就从参数表中顺序取一个值,每个用户都是‘独立’的取值。

    5.
    select next row: sequence
    update value on:each occurrence

    这个选项意味着,脚本中出现一个参数,就从参数表中顺序取一个值,每个用户都是‘独立’的取值。

    6.
    select next row: sequence
    update value on:once

    这个选项意味着,每个用户都是‘独立’的从参数表中取值,而且只能取一次。

    7.
    select next row:random
    update value on:each iteration

    这个选项的作用是lr会给予每个用户一个‘独立’的随机参数,并且每次迭代,该参数值才会发生更改。

    8.
    select next row: random
    update value on:each occurrence

    这个选项的作用是lr会给予每个用户一个‘独立’的随机参数,并且脚本中出现该参数,该参数值就会发生更改。

    9.
    select next row: random
    update value on:once

    这个选项的作用是lr会给予每个用户一个‘独立’的随机参数,并且场景执行过程中,该参数值不会再更改。
  • LR性能数据分析

    2009-06-12 13:47:00

    Transactions(用户事务分析)
    用户事务分析是站在用户角度进行的基础性能分析。
    1、Transation Sunmmary(事务综述)
    对事务进行综合分析是性能分析的第一步,通过分析测试时间内用户事务的成功与失败情况,可以直接判断出系统是否运行正常。
    2、Average Transaciton Response Time(事务平均响应时间)
    “事务平均响应时间”显示的是测试场景运行期间的每一秒内事务执行所用的平均时间,通过它可以分析测试场景运行期间应用系统的性能走向。
    例:随着测试时间的变化,系统处理事务的速度开始逐渐变慢,这说明应用系统随着投产时间的变化,整体性能将会有下降的趋势。
    3、Transactions per Second(每秒通过事务数/TPS)
    “每秒通过事务数/TPS”显示在场景运行的每一秒钟,每个事务通过、失败以及停止的数量,使考查系统性能的一个重要参数。通过它可以确定系统在任何给定时刻的时间事务负载。分析TPS主要是看曲线的性能走向。
    将它与平均事务响应时间进行对比,可以分析事务数目对执行时间的影响。
    例:当压力加大时,点击率/TPS曲线如果变化缓慢或者有平坦的趋势,很有可能是服务开始出现瓶颈。
    4、Total Transactions per Second(每秒通过事务总数)
    “每秒通过事务总数”显示在场景运行时,在每一秒内通过的事务总数、失败的事务总署以及停止的事务总数。
    5、Transaction Performance Sunmmary(事务性能摘要)
    “事务性能摘要”显示方案中所有事务的最小、最大和平均执行时间,可以直接判断响应时间是否符合用户的要求。
    重点关注事务的平均和最大执行时间,如果其范围不在用户可以接受的时间范围内,需要进行原因分析。
    6、Transaction Response Time Under Load(事务响应时间与负载)
    “事务响应时间与负载”是“正在运行的虚拟用户”图和“平均响应事务时间”图的组合,通过它可以看出在任一时间点事务响应时间与用户数目的关系,从而掌握系统在用户并发方面的性能数据,为扩展用户系统提供参考。此图可以查看虚拟用户负载对执行时间的总体影响,对分析具有渐变负载的测试场景比较有用。
    7、Transaction Response Time(Percentile)(事务响应时间(百分比))
    “事务响应时间(百分比)”是根据测试结果进行分析而得到的综合分析图,也就是工具通过一些统计分析方法间接得到的图表。通过它可以分析在给定事务响应时间范围内能执行的事务百分比。
    8、Transaction Response Time(Distribution)(事务响应时间(分布))
    “事务响应时间(分布)”显示在场景运行过程中,事务执行所用时间的分布,通过它可以了解测试过程中不同响应时间的事务数量。如果系统预先定义了相关事务可以接受的最小和最大事务响应时间,则可以使用此图确定服务器性能是否在可以接受的范围内。

    Web Resources(Web资源分析)
    Web资源分析是从服务器入手对Web服务器的性能分析。
    1、Hits per Second(每秒点击次数)
    “每秒点击次数”,即使运行场景过程中虚拟用户每秒向Web服务器提交的HTTP请求数。
    通过它可以评估虚拟用户产生的负载量,如将其和“平均事务响应时间”图比较,可以查看点击次数对事务性能产生的影响。通过对查看“每秒点击次数”,可以判断系统是否稳定。系统点击率下降通常表明服务器的响应速度在变慢,需进一步分析,发现系统瓶颈所在。
    2、Throughput(吞吐率)
    “吞吐率”显示的是场景运行过程中服务器的每秒的吞吐量。其度量单位是字节,表示虚拟用在任何给定的每一秒从服务器获得的数据量。
    可以依据服务器的吞吐量来评估虚拟用户产生的负载量,以及看出服务器在流量方面的处理能力以及是否存在瓶颈。
    “吞吐率”图和“点击率”图的区别:
    “吞吐率”图,是每秒服务器处理的HTTP申请数。
    “点击率”图,是客户端每秒从服务器获得的总数据量。
    3、HTTP Status Code Summary(HTTP状态代码概要)
    “HTTP状态代码概要”显示场景或会话步骤过程中从Web服务器返回的HTTP状态代码数,该图按照代码分组。HTTP状态代码表示HTTP请求的状态。
    4、HTTP Responses per Second(每秒HTTP响应数)
    “每秒HTTP响应数”是显示运行场景过程中每秒从Web服务器返回的不同HTTP状态代码的数量,还能返回其它各类状态码的信息,通过分析状态码,可以判断服务器在压力下的运行情况,也可以通过对图中显示的结果进行分组,进而定位生成错误的代码脚本。
    5、Pages Downloader per Second(每秒下载页面数)
    “每秒下载页面数”显示场景或会话步骤运行的每一秒内从服务器下载的网页数。使用此图可依据下载的页数来计算Vuser生成的负载量。
    和吞吐量图一样,每秒下载页面数图标是Vuser在给定的任一秒内从服务器接收到的数据量。但是吞吐量考虑的各个资源极其大小(例,每个GIF文件的大小、每个网页的大小)。而每秒下载页面数只考虑页面数。
    注:要查看每秒下载页数图,必须在R-T-S那里设置“每秒页面数(仅HTML模式)”。
    6、Retries per Second(每秒重试次数)
    “每秒重试次数”显示场景或会话步骤运行的每一秒内服务器尝试的连接次数。
    在下列情况将重试服务器连接:
    A、初始连接未经授权
    B、要求代理服务器身份验证
    C、服务器关闭了初始连接
    D、初始连接无法连接到服务器
    E、服务器最初无法解析负载生成器的IP地址
    7、Retries Summary(重试次数概要)
    “重试次数概要”显示场景或会话步骤运行过程中服务器尝试的连接次数,它按照重试原因分组。将此图与每秒重试次数图一起使用可以确定场景或会话步骤运行过程中服务器在哪个时间点进行了重试。
    8、Connections(连接数)
    “连接数”显示场景或会话步骤运行过程中每个时间点打开的TCP/IP连接数。
    借助此图,可以知道何时需要添加其他连接。
    例:当连接数到达稳定状态而事务响应时间迅速增大时,添加连接可以使性能得到极大提高(事务响应时间将降低)。
    9、Connections Per Second(每秒连接数)
    “每秒连接数”显示方案在运行过程中每秒建立的TCP/IP连接数。
    理想情况下,很多HTTP请求都应该使用同一连接,而不是每个请求都新打开一个连接。通过每秒连接数图可以看出服务器的处理情况,就表明服务器的性能在逐渐下降。
    10、SSLs Per Second(每秒SSL连接数)
    “每秒SSL连接数”显示场景或会话步骤运行的每一秒内打开的新的以及重新使用的SSL连接数。当对安全服务器打开TCP/IP连接后,浏览器将打开SSL连接。

    Web Page Breakdown(网页元素细分)
    “网页元素细分”主要用来评估页面内容是否影响事务的响应时间,通过它可以深入地分析网站上那些下载很慢的图形或中断的连接等有问题的
    元素。
    1、Web Page Breakdown(页面分解总图)
    “页面分解”显示某一具体事务在测试过程的响应情况,进而分析相关的事务运行是否正常。
    “页面分解”图可以按下面四种方式进行进一步细分:
    1)、Download Time Breaddown(下载时间细分)
    “下载时间细分”图显示网页中不同元素的下载时间,同时还可按照下载过程把时间进行分解,用不同的颜色来显示DNS解析时间、建立连接时间、第一次缓冲时间等各自所占比例。
    2)、Component Breakdown(Over Time)(组件细分(随时间变化))
    “组件细分”图显示选定网页的页面组件随时间变化的细分图。通过该图可以很容易的看出哪些元素在测试过程中下载时间不稳定。该图特别适用于需要在客户端下载控件较多的页面,通过分析控件的响应时间,很容易就能发现那些控件不稳定或者比较耗时。
    3)、Download Time Breakdown(Over Time)(下载时间细分(随时间变化))
    “下载时间细分(随时间变化)” 图显示选定网页的页面元素下载时间细分(随时间变化)情况,它非常清晰地显示了页面各个元素在压力测试过程中的下载情况。
    “下载时间细分”图显示的是整个测试过程页面元素响应的时间统计分析结果,“下载时间细分(随时间变化)”显示的事场景运行过程中每一秒内页面元素响应时间的统计结果,两者分别从宏观和微观角度来分析页面元素的下载时间。
    4)、Time to First Buffer Breakdown(Over Time)(第一次缓冲时间细分(随时间变化))
    “第一次缓冲时间细分(随时间变化)”图显示成功收到从Web服务器返回的第一次缓冲之前的这段时间,场景或会话步骤运行的每一秒中每个网页组件的服务器时间和网络时间(以秒为单位)。可以使用该图确定场景或会话步骤运行期间服务器或网络出现问题的时间。
    First Buffer Time:是指客户端与服务器端建立连接后,从服务器发送第一个数据包开始计时,数据经过网络传送到客户端,到浏览器接收到第一个缓冲所用的时间。
    2、Page Component Breakdown(页面组件细分)
    “页面组件细分”图显示每个网页及其组件的平均下载时间(以秒为单位)。可以根据下载组件所用的平均秒数对图列进行排序,通过它有助于隔离有问题的组件。
    3、Page Component Breakdown(Over Time)(页面组件分解(随时间变化))
    “页面组件分解(随时间变化)”图显示在方案运行期间的每一秒内每个网页及其组件的平均响应时间 (以秒为单位)。
    4、Page Download Time Breakdown(页面下载时间细分)
    “页面下载时间细分”图显示每个页面组件下载时间的细分,可以根据它确定在网页下载期间事务响应时间缓慢是由网络错误引起还是由服务器错误引起。
    “页面下载时间细分”图根据DNS解析时间、连接时间、第一次缓冲时间、SSL握手时间、接收时间、FTP验证时间、客户端时间和错误时间来对每个组件的下载过程进行细分。
    5、Page Download Time Breakdown(Over Time)(页面下载时间细分(随时间变化))
    “页面下载时间细分(随时间变化)”图显示方案运行期间,每一秒内每个页面组件下载时间的细分。使用此图可以确定网络或服务器在方案执行期间哪一时间点发生了问题。
    “页面组件细分(随时间变化)”图和“页面下载时间细分(随时间变化)”图通常结合起来进行分析:首先确定有问题的组件,然后分析它们的下载过程,进而定位原因在哪里。
    6、Time to First Buffer Breakdown(第一次缓冲时间细分)
    “第一次缓冲时间细分”图显示成功收到从Web服务器返回的第一次缓冲之前的这一段时间内的每个页面组件的相关服务器/网路时间。如果组件的下载时间很长,则可以使用此图确定产生的问题与服务器有关还是与网络有关。
    网络时间:定义为第一个HTTP请求那一刻开始,直到确认为止所经过的平均时间。
    服务器时间:定义为从收到初始HTTP请求确认开始,直到成功收到来自Web服务器的一次缓冲为止所经过的平均时间。
    7、Time to First Buffer Breakdown(Over Time)(第一次缓冲时间细分(随时间变化))
    “第一次缓冲时间细分(随时间变化)”图显示成功收到从Web服务器返回的第一个缓冲之前的这段时间内,场景运行的每一秒中每个网页组件的服务器时间和网络时间。可以使用此图确定场景运行期间服务器或网络出现问题的时间点。
    8、Downloader Component Size(KB)(已下载组件大小)
    “已下载组件大小”图显示每个已经下载的网页组建的大小。通过它可以直接看出哪些组件比较大并需要进一步进行优化以提高性能。
  • LR 问题收集

    2009-06-11 19:48:53

    1.LoadRunner超时错误:在录制Web协议脚本回放时超时情况经常出现,产生错误的原因也有很多,解决的方法也不同。

      错误现象1:Action.c(16): Error -27728: Step download timeout (120 seconds) has expired when downloading non-resource(s)。

      错误分析:对于HTTP协议,默认的超时时间是120秒(可以在LoadRunner中修改),客户端发送一个请求到服务器端,如果超过120秒服务器端还没有返回结果,则出现超时错误。

      解决办法:首先在运行环境中对超时进行设置,默认的超时时间可以设置长一些,再设置多次迭代运行,如果还有超时现象,需要在“Runtime Setting”>“Internet Protocol:Preferences”>“Advanced”区域中设置一个“winlnet replay instead of sockets”选项,再回放是否成功。

      错误现象2:Action.c(81):Continuing after Error -27498: Timed out while processing URL=http://172.18.20.70:7001/workflow/bjtel/leasedline/ querystat/ subOrderQuery.do

      错误分析:这种错误常常是因为并发压力过大,服务器端太繁忙,无法及时响应客户端的请求而造成的,所以这个错误是正常现象,是压力过大造成的。

      如果压力很小就出现这个问题,可能是脚本某个地方有错误,要仔细查看脚本,提示的错误信息会定位某个具体问题发生的位置。

      解决办法:例如上面的错误现象问题定位在某个URL上,需要再次运行一下场景,同时在其他机器上访问此URL。如果不能访问或时间过长,可能是服务器或者此应用不能支撑如此之大的负载。分析一下服务器,最好对其性能进行优化。

      如果再次运行场景后还有超时现象,就要在各种图形中分析一下原因,例如可以查看是否服务器、DNS、网络等方面存在问题。

      最后,增加一下运行时的超时设置,在“Run-Time Settings”>“Internet Protocol:Preferences”中,单击“options”,增加“HTTP-request connect timeout” 或者“HTTP-request receive”的值。

    2.LoadRunner脚本中出现乱码:在录制Web协议脚本时出现中文乱码,在回放脚本时会使回放停止在乱码位置,脚本无法运行。

      错误现象:某个链接或者图片名称为中文乱码,脚本运行无法通过。

      错误分析:脚本录制可能采用的是URL-based script方式,如果程序定义的字符集合采用的是国际标准,脚本就会出现乱码现象。

      解决办法:重新录制脚本,在录制脚本前,打开录制选项配置对话框进行设置,在“Recording Options”的“Advanced”选项里先将“Surport Charset”选中,然后选中支持“UTF-8”的选项。

    3.LoadRunner HTTP服务器状态代码:在录制Web协议脚本回放脚本的过程中,会出现HTTP服务器状态代码,例如常见的页面-404错误提示、-500错误提示。

      错误现象1:-404 Not Found服务器没有找到与请求URI相符的资源,但还可以继续运行直到结束。

      错误分析:此处与请求URI相符的资源在录制脚本时已经被提交过一次,回放时不可再重复提交同样的资源,而需要更改提交资源的内容,每次回放一次脚本都要改变提交的数据,保证模拟实际环境,造成一定的负载压力。

      解决办法:在出现错误的位置进行脚本关联,在必要时插入相应的函数。

      错误现象2:-500 Internal Server Error服务器内部错误,脚本运行停止。

      错误分析:服务器碰到了意外情况,使其无法继续回应请求。

      解决办法:出现此错误是致命的,说明问题很严重,需要从问题的出现位置进行检查,此时需要此程序的开发人员配合来解决,而且产生的原因根据实际情况来定,测试人员无法单独解决问题,而且应该尽快解决,以便于后面的测试。

    4.LoadRunner请求无法找到:在录制Web协议脚本回放脚本的过程中,会出现请求无法找到的现象,而导致脚本运行停止。

      错误现象:Action.c(41): Error -27979: Requested form. not found [MsgId: MERR-27979]

      Action.c(41): web_submit_form. highest severity level was “ERROR”,0 body bytes, 0 header bytes [MsgId: MMSG-27178]”

      这时在tree view中看不到此组件的相关URL。

      错误分析:所选择的录制脚本模式不正确,通常情况下,基于浏览器的Web应用会使用“HTML-based script”模式来录制脚本;而没有基于浏览器的Web应用、Web应用中包含了与服务器进行交互的Java Applet、基于浏览器的应用中包含了向服务器进行通信的JavaScript/VBScript代码、基于浏览器的应用中使用HTTPS安全协议,这时则使用“URL-based script”模式进行录制。

      解决办法:打开录制选项配置对话框进行设置,在“Recording Options”的“Internet Protocol”选项里的“Recording”中选择“Recording Level”为“HTML-based script”,单击“HTML Advanced”,选择“Script. Type”为“A script. containing explicit”。然后再选择使用“URL-based script”模式来录制脚本。

    5.LoadRunner不执行检查方法:在录制Web协议脚本中添加了检查方法Web_find,但是在脚本回放的过程中并没有执行。

      错误现象:在脚本中插入函数Web_find,在脚本中设置文本以及图像的检查点,但是在回放过程中并没有对设置的检查点进行检查,即Web_find失效。

      错误分析:由于检查功能会消耗一定的资源,因此LoadRunner默认关闭了对文本以及图像的检查,所以在设置检查点后,需要开启检查功能。

      解决办法:打开运行环境设置对话框进行设置,在“Run-time Settings”的“Internet Protocol”选项里的“Perference”中勾选“Check”下的“Enable Image and text check”选项。

    6.LoadRunner回放Web Services协议脚本错误:LoadRunner 8.0版本在录制Web Services协议的脚本时正常,但在回放时会出现错误,提示停止脚本运行。

      错误现象:利用LoadRunner 8.0版本来录制Web Services协议的脚本没有任何错误提示,回放脚本时会出现如下错误提示“Error:server returned an incorrectly formatted SOAP response”。

      错误分析:出现此错误的原因是LoadRunner8.0在录制Web Services协议的脚本时存在一个缺陷:如果服务器的操作系统是中文的,VuGen会自动将WSDL文件的头改为<?xml version=”1.0″encoding=”zh_cn” ?>,所以才会有此错误提示。

      解决办法:下载两个补丁,分别为“LR80WebServicesFPI_setup.exe”和“lrunner_web_ services_patch_1.exe”安装上即可。

  • 增加测试用例状态的精确度(转载)

    2009-06-11 16:34:51

    增加测试用例状态的精确度

    一般在工作中记录测试用例状态用到三种状态:通过(Pass),失败(Fail)和排队等待中(In Queue)。但是我倾向与更准确地表示一个一般测试用例的生命周期,尽管你的测试的周期会有变化。这里列出了我所使用的一个测试用例生命周期:

    排队(In Queue):测试用例已经指定给某个测试人,不准备在这一个测试阶段运行。

    进行中(IP):该测试正在进行,并且会持续一段时间。(如果一个测试所需要的时间少于一天,我就不会讲一个测试标为进行中,因为我每天会跟踪测试用例的状态)

          阻塞(Block):一些因素会导致测试不能进行到底,例如某个功能欠缺或者测试环境的某个部分欠缺。我通常会在测试用例总结工作表的意见栏记录下阻塞的状态。你可以把阻塞理解为:我希望运行测试,但是目前还不能运行测试。

    跳过(Skip):你决定在当前测试阶段跳过某个测试,可能是因为它的优先权相对较低。(同样地,我会在测试用例总结工作表的意见栏记录下我跳过这个测试的原因。)你可以把跳过理解为:我现在可以运行这个测试,但是我不想运行它。      

         通过(Pass):测试运行结束,测试人得到了预料中的测试结果状态和测试行为。


           失败(Fail):在很多情况下,测试人得到预料之外的测试结果,状态或行为,这些结果与测试目标相差甚远。这就引发了关于系统质量的疑问。一个或多个测试错误需要记录下来。


    警告(Warn):在很多情况下,测试人得到预料之外的测试结果,状态或行为,但是这些结果与测试目标差别不是很大(我通常会在测试包总结工作表的通过一栏记为警告,而不是另加一栏)。另一种想法是,警告意味着当前的错误是无关紧要的,或者对正在测试的特征是没有意义的。系统报出了更多的错。我处理这个问题的一个标准是只和延期的或不是一定要改的错误相关的测试可以标记为警告,而不是失败。

    关闭(Close):一个测试在第一个循环种被标为失败或警告,第二个测试发布中将第一个测试循环出现的错误修改了。重新运行了整个测试用例后,没有错误出现。将这类测试标记为关闭而不是通过,使得你可以跟踪测试在某一个测试发布中失败的实事(同标记为警告的测试一样,我在测试包总结工作表中将标记为关闭的测试也纳入成功的范畴)。

  • 测试路上谨慎新走

    2009-06-11 13:55:52

       工作了才发现,原来开发是不会按照需求来开发的,或者说他们不会仔细的看需求文档,原本我以为严格按照需求开发是应该的,实际上不是,所以测试人员要严格按照需求来测试,有冲突要和负责人商量,不能听开放说需求改了就认为是需求改了。。。。。

        还有有些地方要和开发区分析需求,分析需求应该怎么理解,应该怎么做

       需求,一定要认真看

  • LR使用虚拟IP地址

    2009-06-09 09:14:26

    设置虚拟IP地址
     
      首先,load Generator机器必须使用固定的IP,不能使用动态IP
     
      确定网络中不冲突的IP地址
     
      打开:开始-〉程序-〉loadrunner-〉tools-〉ip wizard,如图
     
     

     

    说明:增加新IP选择第一项;使用保存的文件增加IP选择第二项;释放已经设置的IP选择第三项。

    点“下一步”,如图

     

        此步让输入web serverIP地址(尚不清楚有何意义),不输入,直接点‘下一步’,如图:

     

    说明:使用remove按钮可以删除选定的虚拟IP

    add按钮,如图:

     

        说明:‘检查新IP是否已经存在’选项并没有起作用;根据输入的IP的第一个值和数量,自动添加到虚拟IP列表中,例如:192.168.67.140  4,则增加的虚拟IP是:192.168.67.140192.168.67.141192.168.67.142192.168.67.143

        ok按钮,如图:

     

    点“完成”按钮,如图:

     

        说明:使用Save as…可以将本次增加的IP保存成.ips文件,下次再使用时就可以直接选择此文件了。

        点‘OK’按钮即可。

    现在需要重启计算机。

    (重新启动计算机后,设置的虚拟IP都生效了,此时使用ping会发现都能ping通,并且本机的IP也被改成了第一个虚拟IP地址。确认虚拟IP是否都生效的方法:在运行中输入cmd,在命令窗口录入ipconfig/all,然后就能看到已经生效的所有IP)

     

    使用虚拟IP(以手动方案为例)

    controller中,选择 Scenario-Enable IP Spoofer,此项设置允许使用IP欺骗。

        Generators按钮,设置虚拟用户生成器,将虚拟IP地址都添加进去,并连通。如图:

     

     

        连接成功的虚拟用户生成器会在工具栏中显示,如图:

     

     

    然后设计方案,如下图例子:

     

     

     

        运行方案。

     

    使用虚拟IP测试完成后

    打开IP Wizard,释放所有虚拟IP

    重新启动计算机

  • 50种方法巧妙优化SQL Server数据库--4

    2009-03-13 20:44:21

    3、高程序运行效率,优化应用程序,在SP编写过程中应该注意以下几点:

    a)SQL的使用规范:

    i. 尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。

    ii. 尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接。

    iii. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该改写;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。

    iv. 注意where字句写法,必须考虑语句顺序,应该根据索引顺序、范围大小来确定条件子句的前后顺序,尽可能的让字段顺序与索引顺序相一致,范围从大到小。

    v. 不要在where子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    vi. 尽量使用exists代替select count(1)来判断是否存在记录,count函数只有在统计表中所有行数时使用,而且count(1)比count(*)更有效率。

    vii. 尽量使用“>=”,不要使用“>”。

    viii. 注意一些or子句和union子句之间的替换

    ix. 注意表之间连接的数据类型,避免不同类型数据之间的连接。

    x. 注意存储过程中参数和数据类型的关系。

    xi. 注意insert、update操作的数据量,防止与其他应用冲突。如果数据量超过200个数据页面(400k),那么系统将会进行锁升级,页级锁会升级成表级锁。

    b)索引的使用规范:

    i. 索引的创建要与应用结合考虑,建议大的OLTP表不要超过6个索引。

    ii. 尽可能的使用索引字段作为查询条件,尤其是聚簇索引,必要时可以通过index index_name来强制指定索引

    iii. 避免对大表查询时进行table scan,必要时考虑新建索引。

    iv. 在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。

    v. 要注意索引的维护,周期性重建索引,重新编译存储过程。

    c)tempdb的使用规范:

    i. 尽量避免使用distinct、order by、group by、having、join、cumpute,因为这些语句会加重tempdb的负担。

    ii. 避免频繁创建和删除临时表,减少系统表资源的消耗。

    iii. 在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。

    iv. 如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。

    v. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。

    vi. 慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。

    d)合理的算法使用:

    根据上面已提到的SQL优化技术和ASE Tuning手册中的SQL优化内容,结合实际应用,采用多种算法进行比较,以获得消耗资源最少、效率最高的方法。具体可用ASE调优命令:set statistics io on, set statistics time on , set showplan on 等。

  • 50种方法巧妙优化SQL Server数据库--3

    2009-03-13 20:42:20

    16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引

    17、注意UNion和UNion all 的区别。UNION all好

    18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的

    19、查询时不要返回不需要的行、列

    20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间

    21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行

    22、在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。也不要在Where字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:Where SUBSTRING(firstname,1,1) = 'm'改为Where firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能优化她,而"<>"等还是不能优化,用不到索引。

    23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

    24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: Select * FROM PersonMember (INDEX = IX_Title) Where processid IN ('男','女')

    25、将需要查询的结果预先计算好放在表中,查询的时候再Select。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

    26、MIN() 和 MAX()能使用到合适的索引。

    27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。

    28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌Insert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

    29、Between在某些时候比IN 速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女' 是一样的。由于in会在比较多次,所以有时会慢些。

    30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。

    31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。

    32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。

    33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。

    34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。

    select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345',

    'JCNAD00333138','JCNAD00303570','JCNAD00303569',

    'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933',

    'JCNAD00254567','JCNAD00254585','JCNAD00254608',

    'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618',

    'JCNAD00279196','JCNAD00268613') order by postdate desc

    35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。

    36、当用Select INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中Select * from sysobjects可以看到 Select INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。

    37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快

    38、一次更新多条记录比分多次更新每次一条快,就是说批处理好

    39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好

    40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:

    a、计算字段的表达是确定的

    b、不能用在TEXT,Ntext,Image数据类型

    c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….

    41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程

    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快

    43、Select COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的!!!

    44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。

    45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现

    46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。

  • 50种方法巧妙优化SQL Server数据库--2

    2009-03-13 20:39:44

    16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引

    17、注意UNion和UNion all 的区别。UNION all好

    18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的

    19、查询时不要返回不需要的行、列

    20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间

    21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行

    22、在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。也不要在Where字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:Where SUBSTRING(firstname,1,1) = 'm'改为Where firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能优化她,而"<>"等还是不能优化,用不到索引。

    23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

    24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: Select * FROM PersonMember (INDEX = IX_Title) Where processid IN ('男','女')

    25、将需要查询的结果预先计算好放在表中,查询的时候再Select。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

    26、MIN() 和 MAX()能使用到合适的索引。

    27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。

    28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌Insert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

    29、Between在某些时候比IN 速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女' 是一样的。由于in会在比较多次,所以有时会慢些。

    30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。

    31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。

    32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。

    33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。

    34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。

    select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345',

    'JCNAD00333138','JCNAD00303570','JCNAD00303569',

    'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933',

    'JCNAD00254567','JCNAD00254585','JCNAD00254608',

    'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618',

    'JCNAD00279196','JCNAD00268613') order by postdate desc

    35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。

    36、当用Select INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中Select * from sysobjects可以看到 Select INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。

    37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快

    38、一次更新多条记录比分多次更新每次一条快,就是说批处理好

    39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好

    40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:

    a、计算字段的表达是确定的

    b、不能用在TEXT,Ntext,Image数据类型

    c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….

    41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程

    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快

    43、Select COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的!!!

    44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。

    45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现

    46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。

  • 50种方法巧妙优化SQL Server数据库--2

    2009-03-13 20:39:44

    16、用Profiler来跟踪查询,得到查询所需的时间,找出SQL的问题所在;用索引优化器优化索引

    17、注意UNion和UNion all 的区别。UNION all好

    18、注意使用DISTINCT,在没有必要时不要用,它同UNION一样会使查询变慢。重复的记录在查询里是没有问题的

    19、查询时不要返回不需要的行、列

    20、用sp_configure 'query governor cost limit'或者SET QUERY_GOVERNOR_COST_LIMIT来限制查询消耗的资源。当评估查询消耗的资源超出限制时,服务器自动取消查询,在查询之前就扼杀掉。 SET LOCKTIME设置锁的时间

    21、用select top 100 / 10 Percent 来限制用户返回的行数或者SET ROWCOUNT来限制操作的行

    22、在SQL2000以前,一般不要用如下的字句: "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", and "LIKE '%500'",因为他们不走索引全是表扫描。也不要在Where字句中的列名加函数,如Convert,substring等,如果必须用函数的时候,创建计算列再创建索引来替代.还可以变通写法:Where SUBSTRING(firstname,1,1) = 'm'改为Where firstname like 'm%'(索引扫描),一定要将函数和列名分开。并且索引不能建得太多和太大。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS ,IN , LEFT OUTER JOIN 来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作.如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能优化她,而"<>"等还是不能优化,用不到索引。

    23、使用Query Analyzer,查看SQL语句的查询计划和评估分析是否是优化的SQL。一般的20%的代码占据了80%的资源,我们优化的重点是这些慢的地方。

    24、如果使用了IN或者OR等时发现查询没有走索引,使用显示申明指定索引: Select * FROM PersonMember (INDEX = IX_Title) Where processid IN ('男','女')

    25、将需要查询的结果预先计算好放在表中,查询的时候再Select。这在SQL7.0以前是最重要的手段。例如医院的住院费计算。

    26、MIN() 和 MAX()能使用到合适的索引。

    27、数据库有一个原则是代码离数据越近越好,所以优先选择Default,依次为Rules,Triggers, Constraint(约束如外健主健CheckUNIQUE……,数据类型的最大长度等等都是约束),Procedure.这样不仅维护工作小,编写程序质量高,并且执行的速度快。

    28、如果要插入大的二进制值到Image列,使用存储过程,千万不要用内嵌Insert来插入(不知JAVA是否)。因为这样应用程序首先将二进制值转换成字符串(尺寸是它的两倍),服务器受到字符后又将他转换成二进制值.存储过程就没有这些动作: 方法:Create procedure p_insert as insert into table(Fimage) values (@image), 在前台调用这个存储过程传入二进制参数,这样处理速度明显改善。

    29、Between在某些时候比IN 速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 select * from chineseresume where title in ('男','女') Select * from chineseresume where between '男' and '女' 是一样的。由于in会在比较多次,所以有时会慢些。

    30、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。

    31、不要建没有作用的事物例如产生报表时,浪费资源。只有在必要使用事物时使用它。

    32、用OR的字句可以分解成多个查询,并且通过UNION 连接多个查询。他们的速度只同是否使用索引有关,如果查询需要用到联合索引,用UNION all执行的效率更高.多个OR的字句没有用到索引,改写成UNION的形式再试图与索引匹配。一个关键的问题是否用到索引。

    33、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用stored procedure来代替她。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图,直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。

    34、没有必要时不要用DISTINCT和ORDER BY,这些动作可以改在客户端执行。它们增加了额外的开销。这同UNION 和UNION ALL一样的道理。

    select top 20 ad.companyname,comid,position,ad.referenceid,worklocation, convert(varchar(10),ad.postDate,120) as postDate1,workyear,degreedescription FROM jobcn_query.dbo.COMPANYAD_query ad where referenceID in('JCNAD00329667','JCNAD132168','JCNAD00337748','JCNAD00338345',

    'JCNAD00333138','JCNAD00303570','JCNAD00303569',

    'JCNAD00303568','JCNAD00306698','JCNAD00231935','JCNAD00231933',

    'JCNAD00254567','JCNAD00254585','JCNAD00254608',

    'JCNAD00254607','JCNAD00258524','JCNAD00332133','JCNAD00268618',

    'JCNAD00279196','JCNAD00268613') order by postdate desc

    35、在IN后面值的列表中,将出现最频繁的值放在最前面,出现得最少的放在最后面,减少判断的次数。

    36、当用Select INTO时,它会锁住系统表(sysobjects,sysindexes等等),阻塞其他的连接的存取。创建临时表时用显示申明语句,而不是 select INTO. drop table t_lxh begin tran select * into t_lxh from chineseresume where name = 'XYZ' --commit 在另一个连接中Select * from sysobjects可以看到 Select INTO 会锁住系统表,Create table 也会锁系统表(不管是临时表还是系统表)。所以千万不要在事物内使用它!!!这样的话如果是经常要用的临时表请使用实表,或者临时表变量。

    37、一般在GROUP BY 个HAVING字句之前就能剔除多余的行,所以尽量不要用它们来做剔除行的工作。他们的执行顺序应该如下最优:select 的Where字句选择所有合适的行,Group By用来分组个统计行,Having字句用来剔除多余的分组。这样Group By 个Having的开销小,查询快.对于大的数据行进行分组和Having十分消耗资源。如果Group BY的目的不包括计算,只是分组,那么用Distinct更快

    38、一次更新多条记录比分多次更新每次一条快,就是说批处理好

    39、少用临时表,尽量用结果集和Table类性的变量来代替它,Table 类型的变量比临时表好

    40、在SQL2000下,计算字段是可以索引的,需要满足的条件如下:

    a、计算字段的表达是确定的

    b、不能用在TEXT,Ntext,Image数据类型

    c、必须配制如下选项 ANSI_NULLS = ON, ANSI_PADDINGS = ON, …….

    41、尽量将数据的处理工作放在服务器上,减少网络的开销,如使用存储过程。存储过程是编译好、优化过、并且被组织到一个执行规划里、且存储在数据库中的SQL语句,是控制流语言的集合,速度当然快。反复执行的动态SQL,可以使用临时存储过程,该过程(临时表)被放在Tempdb中。以前由于SQL SERVER对复杂的数学计算不支持,所以不得不将这个工作放在其他的层上而增加网络的开销。SQL2000支持UDFs,现在支持复杂的数学计算,函数的返回值不要太大,这样的开销很大。用户自定义函数象光标一样执行的消耗大量的资源,如果返回大的结果采用存储过程

    42、不要在一句话里再三的使用相同的函数,浪费资源,将结果放在变量里再调用更快

    43、Select COUNT(*)的效率教低,尽量变通他的写法,而EXISTS快.同时请注意区别: select count(Field of null) from Table 和 select count(Field of NOT null) from Table 的返回值是不同的!!!

    44、当服务器的内存够多时,配制线程数量 = 最大连接数+5,这样能发挥最大的效率;否则使用 配制线程数量<最大连接数启用SQL SERVER的线程池来解决,如果还是数量 = 最大连接数+5,严重的损害服务器的性能。

    45、按照一定的次序来访问你的表。如果你先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果你(不经意的)某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。如果锁定顺序没有被预先详细的设计好,死锁很难被发现

    46、通过SQL Server Performance Monitor监视相应硬件的负载 Memory: Page Faults / sec计数器如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。

  • 50种方法巧妙优化SQL Server数据库--1

    2009-03-13 20:35:33

    查询速度慢的原因很多,常见如下几种:

    1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)

    2、I/O吞吐量小,形成了瓶颈效应。

    3、没有创建计算列导致查询不优化。

    4、内存不足

    5、网络速度慢

    6、查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)

    7、锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)

    8、sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。

    9、返回了不必要的行和列

    10、查询语句不好,没有优化

    可以通过如下方法来优化查询 :

    1、把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要.

    2、纵向、横向分割表,减少表的尺寸(sp_spaceuse)

    3、升级硬件

    4、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。注意填充因子要适当(最好是使用默认值0)。索引应该尽量小,使用字节数小的列建索引好(参照索引的创建),不要对有限的几个值的字段建单一索引如性别字段

    5、提高网速;

    6、扩大服务器的内存,Windows 2000和SQL server 2000能支持4-8G的内存。配置虚拟内存:虚拟内存大小应基于计算机上并发运行的服务进行配置。运行 Microsoft SQL Server? 2000 时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的 1.5 倍。如果另外安装了全文检索功能,并打算运行 Microsoft 搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为至少是计算机中安装的物理内存的 3 倍。将 SQL Server max server memory 服务器配置选项配置为物理内存的 1.5 倍(虚拟内存大小设置的一半)。

    7、增加服务器 CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。使用并行还是串行程是MsSQL自动评估选择的。单个任务分解成多个任务,就可以在处理器上运行。例如耽搁查询的排序、连接、扫描和GROUP BY字句同时执行,SQL SERVER根据系统的负载情况决定最优的并行等级,复杂的需要消耗大量的CPU的查询最适合并行处理。但是更新操作Update,Insert, Delete还不能并行处理。

    8、如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like 'a%' 使用索引 like '%a' 不使用索引用 like '%a%' 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。

    9、DB Server 和APPLication Server 分离;OLTP和OLAP分离

    10、分布式分区视图可用于实现数据库服务器联合体。联合体是一组分开管理的服务器,但它们相互协作分担系统的处理负荷。这种通过分区数据形成数据库服务器联合体的机制能够扩大一组服务器,以支持大型的多层 Web 站点的处理需要。有关更多信息,参见设计联合数据库服务器。(参照SQL帮助文件'分区视图')

    a、在实现分区视图之前,必须先水平分区表

    b、在创建成员表后,在每个成员服务器上定义一个分布式分区视图,并且每个视图具有相同的名称。这样,引用分布式分区视图名的查询可以在任何一个成员服务器上运行。系统操作如同每个成员服务器上都有一个原始表的复本一样,但其实每个服务器上只有一个成员表和一个分布式分区视图。数据的位置对应用程序是透明的。

    11、重建索引 DBCC REINDEX ,DBCC INDEXDEFRAG,收缩数据和日志 DBCC SHRINKDB,DBCC SHRINKFILE. 设置自动收缩日志.对于大的数据库不要设置数据库自动增长,它会降低服务器的性能。在T-sql的写法上有很大的讲究,下面列出常见的要点:首先,DBMS处理查询计划的过程是这样的:

    1、 查询语句的词法、语法检查

    2、 将语句提交给DBMS的查询优化器

    3、 优化器做代数优化和存取路径的优化

    4、 由预编译模块生成查询规划

    5、 然后在合适的时间提交给系统处理执行

    6、 最后将执行结果返回给用户其次,看一下SQL SERVER的数据存放的结构:一个页面的大小为8K(8060)字节,8个页面为一个盘区,按照B树存放。

    12、Commit和rollback的区别 Rollback:回滚所有的事物。 Commit:提交当前的事物. 没有必要在动态SQL里写事物,如果要写请写在外面如: begin tran exec(@s) commit trans 或者将动态SQL 写成函数或者存储过程。

    13、在查询Select语句中用Where字句限制返回的行数,避免表扫描,如果返回不必要的数据,浪费了服务器的I/O资源,加重了网络的负担降低性能。如果表很大,在表扫描的期间将表锁住,禁止其他的联接访问表,后果严重。

    14、SQL的注释申明对执行没有任何影响

    15、尽可能不使用光标,它占用大量的资源。如果需要row-by-row地执行,尽量采用非光标技术,如:在客户端循环,用临时表,Table变量,用子查询,用Case语句等等。游标可以按照它所支持的提取选项进行分类: 只进 必须按照从第一行到最后一行的顺序提取行。FETCH NEXT 是唯一允许的提取操作,也是默认方式。可滚动性可以在游标中任何地方随机提取任意行。游标的技术在SQL2000下变得功能很强大,他的目的是支持循环。有四个并发选项 READ_ONLY:不允许通过游标定位更新(Update),且在组成结果集的行中没有锁。 OPTIMISTIC WITH valueS:乐观并发控制是事务控制理论的一个标准部分。乐观并发控制用于这样的情形,即在打开游标及更新行的间隔中,只有很小的机会让第二个用户更新某一行。当某个游标以此选项打开时,没有锁控制其中的行,这将有助于最大化其处理能力。如果用户试图修改某一行,则此行的当前值会与最后一次提取此行时获取的值进行比较。如果任何值发生改变,则服务器就会知道其他人已更新了此行,并会返回一个错误。如果值是一样的,服务器就执行修改。选择这个并发选项OPTIMISTIC WITH ROW VERSIONING:此乐观并发控制选项基于行版本控制。使用行版本控制,其中的表必须具有某种版本标识符,服务器可用它来确定该行在读入游标后是否有所更改。在 SQL Server 中,这个性能由 timestamp 数据类型提供,它是一个二进制数字,表示数据库中更改的相对顺序。每个数据库都有一个全局当前时间戳值:@@DBTS。每次以任何方式更改带有 timestamp 列的行时,SQL Server 先在时间戳列中存储当前的 @@DBTS 值,然后增加 @@DBTS 的值。如果某 个表具有 timestamp 列,则时间戳会被记到行级。服务器就可以比较某行的当前时间戳值和上次提取时所存储的时间戳值,从而确定该行是否已更新。服务器不必比较所有列的值,只需比较 timestamp 列即可。如果应用程序对没有 timestamp 列的表要求基于行版本控制的乐观并发,则游标默认为基于数值的乐观并发控制。

    SCROLL LOCKS 这个选项实现悲观并发控制。在悲观并发控制中,在把数据库的行读入游标结果集时,应用程序将试图锁定数据库行。在使用服务器游标时,将行读入游标时会在其上放置一个更新锁。如果在事务内打开游标,则该事务更新锁将一直保持到事务被提交或回滚;当提取下一行时,将除去游标锁。如果在事务外打开游标,则提取下一行时,锁就被丢弃。因此,每当用户需要完全的悲观并发控制时,游标都应在事务内打开。更新锁将阻止任何其它任务获取更新锁或排它锁,从而阻止其它任务更新该行。然而,更新锁并不阻止共享锁,所以它不会阻止其它任务读取行,除非第二个任务也在要求带更新锁的读取。滚动锁根据在游标定义的 Select 语句中指定的锁提示,这些游标并发选项可以生成滚动锁。滚动锁在提取时在每行上获取,并保持到下次提取或者游标关闭,以先发生者为准。下次提取时,服务器为新提取中的行获取滚动锁,并释放上次提取中行的滚动锁。滚动锁独立于事务锁,并可以保持到一个提交或回滚操作之后。如果提交时关闭游标的选项为关,则 COMMIT 语句并不关闭任何打开的游标,而且滚动锁被保留到提交之后,以维护对所提取数据的隔离。所获取滚动锁的类型取决于游标并发选项和游标 Select 语句中的锁提示。锁提示 只读 乐观数值 乐观行版本控制 锁定无提示 未锁定 未锁定 未锁定 更新 NOLOCK 未锁定 未锁定未锁定 未锁定 HOLDLOCK 共享 共享 共享 更新 UPDLOCK 错误 更新 更新 更新 TABLOCKX 错误 未锁定 未锁定更新其它 未锁定 未锁定 未锁定 更新 *指定 NOLOCK 提示将使指定了该提示的表在游标内是只读的。

  • Linux下的shell编程入门(2)

    2009-03-05 21:52:46

    1.建立和运行shell程序
    什么是shell程序呢? 简单的说shell程序就是一个包含若干行
    shell或者linux命令的文件.
    象编写高级语言的程序一样,编写一个shell程序需要一个文本编辑器.如VI等.
    在文本编辑环境下,依据shell的语法规则,输入一些shell/linux命令行,形成一个完整
    的程序文件.
    执行shell程序文件有三种方法
    (1)#chmod +x file(在/etc/profile中,加入export PATH=${PATH}:~/yourpath,就可以在命令行下直接运行,像执行普通命令一样)
    (2)#sh file
    (3)# . file
    (4)#source file
    在编写shell时,第一行一定要指明系统需要那种shell解释你的shell程序,如:#! /bin/bash,
    #! /bin/csh,/bin/tcsh,还是#! /bin/pdksh .
    2.shell中的变量
    (1)常用系统变量
         $ #        :保存程序命令行参数的数目
         $ ?        :保存前一个命令的返回码
         $ 0        :保存程序名
         $ *        :以("$1 $2...")的形式保存所有输入的命令行参数
         $ @        :以("$1""$2"...)的形式保存所有输入的命令行参数
    (2)定义变量
       shell语言是非类型的解释型语言,不象用C++/JAVA语言编程时需要事先声明变量.给一
    个变量赋值,实际上就是定义了变量.
       在linux支持的所有shell中,都可以用赋值符号(=)为变量赋值.
    如:
    abc=9 (bash/pdksh不能在等号两侧留下空格 )
    set abc = 9 (tcsh/csh)
       由于shell程序的变量是无类型的,所以用户可以使用同一个变量时而存放字符时而存放
    整数.
    如:
    name=abc (bash/pdksh)
    set name = abc (tcsh)
    在变量赋值之后,只需在变量前面加一个$去引用.
    如:
    echo $abc
    (3)位置变量
    当运行一个支持多个命令行参数的shell程序时,这些变量的值将分别存放在位置变量里.
    其中第一个参数存放在位置变量1,第二个参数存放在位置变量2,依次类推...,shell保留
    这些变量,不允许用户以令外的方式定义他们.同别的变量,用$符号引用他们.

    3.shell中引号的使用方法
    shell使用引号(单引号/双引号)和反斜线("\")用于向shell解释器屏蔽一些特殊字符.
    反引号(")对shell则有特殊意义.
    如:
    abc="how are you" (bash/pdksh)
    set abc = "how are you" (tcsh)
    这个命令行把三个单词组成的字符串how are you作为一个整体赋值给变量abc.
    abc1='@LOGNAME,how are you!' (bash/pdksh)
    set abc1='$LOGNAME,how are you!' (tcsh)
    abc2="$LOGNAME,how are you!" (bash/pdksh)
    set abc2="$LOGNAME,how are you!" (tcsh)
    LOGNAME变量是保存当前用户名的shell变量,假设他的当前值是:wang.执行完两条命令后,
    abc1的内容是:$LOGNAME, how are you!.而abc2的内容是;wang, how are you!.
    象单引号一样,反斜线也能屏蔽所有特殊字符.但是他一次只能屏蔽一个字符.而不能屏蔽
    一组字符.
    反引号的功能不同于以上的三种符号.他不具有屏蔽特殊字符的功能.但是可以通过他将
    一个命令的运行结果传递给另外一个命令.
    如:
    contents=`ls` (bash/pdksh)
    set contents = `ls` (tcsh)
    4.shell程序中的test命令
    在bash/pdksh中,命令test用于计算一个条件表达式的值.他们经常在条件语句和循环
    语句中被用来判断某些条件是否满足.
    test命令的语法格式:
    test expression
    或者
    [expression]

    在test命令中,可以使用很多shell的内部操作符.这些操作符介绍如下:
    (1)字符串操作符 用于计算字符串表达式
    test命令    |    含义
    -----------------------------------------
    Str1 = str2 | 当str1与str2相同时,返回True
    Str1! = str2| 当str1与str2不同时,返回True
         Str      | 当str不是空字符时,返回True
        -n str    | 当str的长度大于0时,返回True
        -z str    | 当str的长度是0时,返回True
    -----------------------------------------
    (2)整数操作符具有和字符操作符类似的功能.只是他们的操作是针对整数
    test表达式   |    含义
    ---------------------------------------------
    Int1 -eq int2|当int1等于int2时,返回True
    Int1 -ge int2|当int1大于/等于int2时,返回True
    Int1 -le int2|当int1小于/等于int2时,返回True
    Int1 -gt int2|当int1大于int2时,返回True
    Int1 -ne int2|当int1不等于int2时,返回True
    -----------------------------------------
    (3)用于文件操作的操作符,他们能检查:文件是否存在,文件类型等
    test表达式   |    含义
    ------------------------------------------------
    -d file      |当file是一个目录时,返回 True
    -f file      |当file是一个普通文件时,返回 True
    -r file      |当file是一个刻读文件时,返回 True
    -s file      |当file文件长度大于0时,返回 True
    -w file      |当file是一个可写文件时,返回 True
    -x file      |当file是一个可执行文件时,返回 True
    ------------------------------------------------
    (4)shell的逻辑操作符用于修饰/连接包含整数,字符串,文件操作符的表达式
    test表达式    |    含义
    ----------------------------------------------------------
    ! expr        |当expr的值是False时,返回True
    Expr1 -a expr2|当expr1,expr2值同为True时,返回True
    Expr1 -o expr2|当expr1,expr2的值至少有一个为True时,返回True
    -----------------------------------------------------------
    注意:
    tcsh shell 不使用test命令,但是tcsh中的表达式同样能承担相同的功能.tcsh
    支持的表达式于C中的表达式相同.通常使用在if和while命令中.
    tcsh表达式    |    含义
    -------------------------------------------------------
    Int1 <= int2 |当int1小于/等于int2时,返回True
    Int1 >= int2 |当int1大于/等于int2时,返回True
    Int1 < int2   |当int1小于int2时,返回True
    Int1 > int2   |当int1大于int2时,返回True
    Str1 == str2 |当str1与str2相同时,返回True
    Str1 != str2 |当str1与str2不同时,返回True
    -r file       |当file是一个可读文件时,返回True
    -w file       |当file是一个可写文件时,返回True
    -x file       |当file是一个可执行文件时,返回True
    -e file       |当file存在时,返回True
    -o file       |当file文件的所有者是当前用户时,返回True
    -z file       |当file长度为0时,返回True
    -f file       |当file是一个普通文件时,返回True
    -d file       |当file是一个目录时,返回True
    Exp1 || exp2 |当exp1和exp2的值至少一个为True时,返回True
    Exp1 && exp2 |当exp1和exp2的值同为True时,返回True
    ! exp         |当exp的值为False时,返回True
  • Linux下的shell编程入门(1)

    2009-03-05 21:52:00

    通常情况下,我们从命令行输入命令每输入一次就能够得到系统的一次响应。一旦需要我们一个接着一个的输入命令而最后才得到结果的时候,这样的做法显然就没有效率。要达到这样的目的,通常我们利用shell程序或者shell脚本来实现。

      一、简介

      Shell编程有很多类似C语言和其他程序语言的特征,但是又没有编程语言那样复杂。Shell程序就是放在一个文件中的一系列Linux命令和实用程序,在执行的时候,通过Linux一个接着一个地解释和执行每个命令。

      下面我们来看一个简单的shell程序:

      1、首先建立一个内容如下的文件,名字为date,将其存放在目录下的bin子目录中。

      #Program date

      #usageto ::show the date in this way (注释)

      echo “Mr.$USER,Today is:”

      echo date “+%B%d%A”

      echo “Whish you a lucky day !”

      2、编辑完该文件之后它还不能执行,我们需要给它设置可执行权限。使用如下命令:

      chmod +x date

      通过以上过程之后,我们就可以像使用ls命令一样执行这个shell程序.

      [beichen@localhost bin]$ date

      Mr.beichen,Today is:

      January 13 Friday

      Whish you a lucky day !

      为了在任何目录里都可以执行这个程序,可以将bin的这个目录添加到路径中去。

      [beichen@localhost bin]$ PATH=$PATH:$HOME/bin

      (注:这里的$HOME代替的是/home/beichen,而bin目录是自己建的一个目录)

      另外一种执行date的方法就是把它作为一个参数传给shell命令:

      [beichen@localhost /]$ bash date

      Mr.beichen,Today is:

      January 13 Friday

      Whish you a lucky day !

      尽管在前面我们使用chmod +x date将date设置为可执行,其实不设置也没有关系,但在Linux里执行它,需要先告诉系统它是一个可执行的脚本。

      [beichen@localhost /]$ .date

      Mr.beichen,Today is:

      January 13 Friday

      Whish you a lucky day !

      即在date前面加上一个点”.”,并且用空格与后面的shell脚本的文件名隔开。当然,不推荐这样做。

      二、shell参数

      如同ls 命令可以接受目录等作为它的参数一样,在shell编程时同样可以使用参数。Shell有位置参数和内部参数。

      1、 位置参数

      由系统提供的参数称为位置参数。位置参数的值可以用$N得到,N是一个数字,如果为1,即$1.类似C语言中的数组,Linux会把输入的命令 字符串分段并给每段进行标号,标号从0开始。第0号为程序名字,从1开始就表示传递给程序的参数。如$0表示程序的名字,$1表示传递给程序的第一个参 数,以此类推。

      2、 内部参数

      上述过程中的$0是一个内部变量,它是必须的,而$1则可有可无。和$0一样的内部变量还有以下几个。

      $# ----传递给程序的总的参数数目

      $? ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。

      $* ----传递给程序的所有参数组成的字符串。

      下面举例进行说明:

      建立一个内容为如下的程序P1:

      echo “Program name is $0”

      echo “There are totally $# parameters passed to this program”

      echo “The last is $?”

      echo “The parameters are $*”

      执行后的结果如下:

      [beichen@localhost bin]$ P1 this is a test program //传递5个参数

      Program name is /home/beichen/bin/P1 //给出程序的完整路径和名字

      There are totally 5 parameters passed to this program //参数的总数

      The last is 0 //程序执行结果

      The parameters are this is a test program //返回有参数组成的字符串

  • Linux主要shell命令详解

    2009-03-05 21:47:13

    shell是用户和Linux操作系统之间的接口。Linux中有多种shell,其中缺省使用的是Bash。
    本章讲述了:
    shell的工作原理,
    shell的种类,
    shell的一般操作,
    Bash的特性。



    (一) 什么是shell

    Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。

    shell是用户和Linux内核之间的接口程序,如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。

    shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。用户在提示符下输入的命令都由shell先解释然后传给Linux核心。

    有一些命令,比如改变工作目录命令cd,是包含在shell内部的。还有一些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的单独的程序。对用户而言,不必关心一个命令是建立在shell内部还是一个单独的程序。

    shell 首先检查命令是否是内部命令,若不是再检查是否是一个应用程序(这里的应用程序可以是Linux本身的实用程序,如ls和rm,也可以是购买的商业程序,如xv,或者是自由软件,如emacs)。然后shell在搜索路径里寻找这些应用程序(搜索路径就是一个能找到可执行程序的目录列表)。如果键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息。如果能够成功找到命令,该内部命令或应用程序将被分解为系统调用并传给 Linux内核。

    shell的另一个重要特性是它自身就是一个解释型的程序设计语言,shell程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、数组和程序控制结构。shell编程语言简单易学,任何在提示符中能键入的命令都能放到一个可执行的shell程序中。

    当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进程提供了命令行提示符。作为默认值(TurboLinux系统默认的shell是BASH),对普通用户用“$”作提示符,对超级用户(root)用“#”作提示符。

    一旦出现了shell提示符,就可以键入命令名称及命令所需要的参数。shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常结束之前,中止它的执行)。

    当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文件结束符(EOF)(按ctrl+d实现),结束登录。




    (二) shell的种类

    Linux 中的shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和Korn shell(ksh)。三种shell各有优缺点。Bourne shell是UNIX最初使用的shell,并且在每种UNIX上都可以使用。Bourne shell在shell编程方面相当优秀,但在处理与用户的交互方面做得不如其他几种shell。Linux操作系统缺省的shell是Bourne Again shell,它是Bourne shell的扩展,简称Bash,与Bourne shell完全向后兼容,并且在Bourne shell的基础上增加、增强了很多特性。Bash放在/bin/bash中,它有许多特色,可以提供如命令补全、命令编辑和命令历史表等功能,它还包含了很多C shell和Korn shell中的优点,有灵活和强大的编程接口,同时又有很友好的用户界面。

    C shell是一种比Bourne shell更适于编程的shell,它的语法与C语言很相似。 Linux为喜欢使用C shell的人提供了Tcsh。Tcsh是C shell的一个扩展版本。Tcsh包括命令行编辑、可编程单词补全、拼写校正、历史命令替换、作业控制和类似C语言的语法,它不仅和Bash shell是提示符兼容,而且还提供比Bash shell更多的提示符参数。

    Korn shell集合了C shell和Bourne shell的优点并且和Bourne shell完全兼容。Linux系统提供了pdksh(ksh的扩展),它支持任务控制,可以在命令行上挂起、后台执行、唤醒或终止程序。

    Linux 并没有冷落其他shell用户,还包括了一些流行的shell如ash、zsh等。每个shell都有它的用途,有些shell是有专利的,有些能从 Internet网上或其他来源获得。要决定使用哪个shell,只需读一下各种shell的联机帮助,并试用一下。

    用户在登录到Linux时由/etc/passwd文件来决定要使用哪个shell。例如:

    # fgrep lisa /etc/passwd

    lisa:x:500:500:TurboLinux User:/home/lisa:/bin/bash

    shell被列每行的末尾(/bin/bash)。

    由于Bash是Linux上缺省的shell,本章主要介绍Bash及其相关知识。



    (三) shell命令

    <1>命令行c

    用户登录到Linux系统时,可以看到一个shell提示符,标识了命令行的开始。用户可以在提示符后面输入任何命令及参数。例如:

    $ date

    二 11 23 01:34:58 CST 1999

    $

    用户登录时,实际进入了shell,它遵循一定的语法将输入的命令加以解释并传给系统。命令行中输入的第一个字必须是一个命令的名字,第二个字是命令的选项或参数,命令行中的每个字必须由空格或TAB隔开,格式如下:

    $ Command Option Arguments

    1. 选项和参数

    选项是包括一个或多个字母的代码,它前面有一个减号(减号是必要的,Linux用它来区别选项和参数),选项可用于改变命令执行的动作的类型。例如:


    大多数命令都被设计为可以接纳参数。参数是在命令行中的选项之后键入的一个或多个单词,例如:

    $ ls -l text

    -rw-r--r-- 2 wzh book 22 Apr 20 20:37 motd

    -rw-r--r-- 2 wzh book 796 Apr 20 20:37 passwd

    $

    将显示text目录下的所有文件及其信息。

    有些命令,如ls可以带参数,而有一些命令可能需要一些最小数目的参数。例如,cp命令至少需要两个参数,如果参数的数目与命令要求不符,shell将会给出出错信息。例如:

    $ cp -i mydata newdata

    注意:命令行中选项先于参数输入。


    2. 命令行特征

    命令行实际上是可以编辑的一个文本缓冲区,在按回车之前,可以对输入的文本进行编辑。比如利用BACKSPACE键可以删除刚键入的字符,可以进行整行删除,还可以插入字符,使得用户在输入命令,尤其是复杂命令时,若出现键入错误,无须重新输入整个命令,只要利用编辑操作,即可改正错误。

    利用上箭头可以重新显示刚执行的命令,利用这一功能可以重复执行以前执行过的命令,而无须重新键入该命令。

    bash 保存着以前键入过的命令的列表,这一列表被称为命令历史表。按动上箭头,便可以在命令行上逐次显示各条命令。同样,按动下箭头可以在命令列表中向下移动,这样可以将以前的各条命令显示在命令行上,用户可以修改并执行这些命令。这一特征将在10.4节中进行详细的论述。

    在一个命令行中还可以置入多个命令,用分号将各个命令隔开。例如:

    $ ls -F;cp -i mydata newdata

    也可以在几个命令行中输入一个命令,用反斜杠将一个命令行持续到下一行。



    <2>shell中的特殊字符

    shell中除使用普通字符外,还可以使用一些具有特殊含义和功能的特殊字符。在使用它们时应注意其特殊的含义和作用范围。下面分别对这些特殊字符加以介绍。

    1. 通配符

    通配符用于模式匹配,如文件名匹配、路经名搜索、字符串查找等。常用的通配符有*、?和括在方括号[ ]中的字符序列。用户可以在作为命令参数的文件名中包含这些通配符,构成一个所谓的“模式串”,在执行过程中进行模式匹配。

    * 代表任何字符串(长度可以不等),例如:“f*”匹配以f打头的任意字符串。但应注意,文件名前的圆点(.)和路经名中的斜线(/)必须显式匹配。例如“*”不能匹配.file,而“.*”才可以匹配.file。

    ? 代表任何单个字符。

    []代表指定的一个字符范围,只要文件名中[]位置处的字符在[]中指定的范围之内,那么这个文件名就与这个模式串匹配。方括号中的字符范围可以由直接给出的字符组成,也可以由表示限定范围的起始字符、终止字符及中间的连字符(-)组成。例如,f [a- d] 与f [abcd]的作用相同。Shell将把与命令行中指定的模式串相匹配的所有文件名都作为命令的参数,形成最终的命令,然后再执行这个命令。


    特别需要注意的是,连字符“-”仅在方括号内有效,表示字符范围,如在方括号外面就成为普通字符了。而*和?只在方括号外面是通配符,若出现在方括号之内,它们也失去通配符的能力,成为普通字符了。例如,模式“- a[*?]abc”中只有一对方括号是通配符,*和?均为普通字符,因此,它匹配的字符串只能是- a*abc和- a?abc。

    最后说明一下使用通配符时需要注意的一些问题。由于*、?和[]对于shell来说具有比较特殊的意义,因此在正常的文件名中不应出现这些字符。特别是在目录名中不要出现它们,否则Shell匹配起来可能会无穷的递归下去。另外要注意的一点是:如果目录中没有与指定的模式串相匹配的文件名,那么Shell将使用此模式串本身作为参数传给有关命令。这可能就是命令中出现特殊字符的原因所在。


    2. 引号

    在shell中引号分为三种:单引号,双引号和反引号。

    * 单引号 ‘

    由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。例如:

    $ string=’$PATH’

    $ echo $string

    $PATH

    可见$保持了其本身的含义,作为普通字符出现。


    * 双引号 “

    由双引号括起来的字符,除$、\、’、和”这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。
    对于$来说,就是用其后指定的变量的值来代替这个变量和$;对于\而言,是转义字符,它告诉shell不要对其后面的那个字符进行特殊处理,只当作普通字符即可。


    * 反引号 `

    反引号(`)这个字符所对应的键一般位于键盘的左上角,不要将其同单引号(’)混淆。反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。


    <3> 注释符

    在shell编程中经常要对某些正文行进行注释,以增加程序的可读性。在Shell中以字符“#”开头的正文行表示注释行。

    此外还有一些特殊字符如:用于输入/输出重定向与管道的<、>、<<、>>和|;执行后台命令的&;命令执行操作符&&和||及表示命令组的{}将在下面各小节中加以介绍。

    标准输入/输出和重定向

    1. 标准输入与输出

    我们知道,执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),通常对应终端的键盘;标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。

    我们以cat命令为例,cat命令的功能是从命令行给出的文件中读取数据,并将这些数据直接送到标准输出。若使用如下命令:

    $ cat config

    将会把文件config的内容依次显示到屏幕上。但是,如果cat的命令行中没有参数,它就会从标准输入中读取数据,并将其送到标准输出。例如:

    用户输入的每一行都立刻被cat命令输出到屏幕上。

    另一个例子,命令sort按行读入文件正文(当命令行中没有给出文件名时,表示从标准输入读入),将其排序,并将结果送到标准输出。下面的例子是从标准输入读入一个采购单,并将其排序。

    $ sort

    bananas

    carrots

    apples

    <ctrl+d>

    apples

    bananas

    carrots

    $

    这时我们在屏幕上得到了已排序的采购单。

    直接使用标准输入/输出文件存在以下问题:

    输入数据从终端输入时,用户费了半天劲输入的数据只能用一次。下次再想用这些数据时就得重新输入。而且在终端上输入时,若输入有误修改起来不是很方便。

    输出到终端屏幕上的信息只能看不能动。我们无法对此输出作更多处理,如将输出作为另一命令的输入进行进一步的处理等。

    为了解决上述问题,Linux系统为输入、输出的传送引入了另外两种机制,即输入/输出重定向和管道。

    2. 输入重定向

    输入重定向是指把命令(或可执行程序)的标准输入重定向到指定的文件中。也就是说,输入可以不来自键盘,而来自一个指定的文件。所以说,输入重定向主要用于改变一个命令的输入源,特别是改变那些需要大量输入的输入源。

    例如,命令wc统计指定文件包含的行数、单词数和字符数。如果仅在命令行上键入:

    $ wc

    wc将等待用户告诉它统计什么,这时shell就好象死了一样,从键盘键入的所有文本都出现在屏幕上,但并没有什么结果,直至按下<ctrl+d>,wc才将命令结果写在屏幕上。

    如果给出一个文件名作为wc命令的参数,如下例所示,wc将返回该文件所包含的行数、单词数和字符数。

    $ wc /etc/passwd

    20 23 726 /etc/passwd

    $

    另一种把/etc/passwd文件内容传给wc命令的方法是重定向wc的输入。输入重定向的一般形式为:命令<文件名。可以用下面的命令把wc命令的输入重定向为/etc/passwd文件:

    $ wc < /etc/passwd

    20 23 726

    $

    另一种输入重定向称为here文档,它告诉shell当前命令的标准输入来自命令行。here文档的重定向操作符使用<<。它将一对分隔符(本例中用delim表示)之间的正文重定向输入给命令。下例将一对分隔符delim之间的正文作为wc命令的输入,统计出正文的行数、单词数和字符数。

    $ wc<<delim

    >this text forms the content

    >of the here document,which

    >continues until the end of

    >text delimter

    >delim

    4 17 98

    在< <操作符后面,任何字符都可以作为正文开始前的分隔符,本例中使用delim作为分隔符。here文档的正文一直延续到遇见另一个分隔符为止。第二个分隔符应出现在新行的开头。这时here文档的正文(不包括开始和结束的分隔符)将重新定向送给命令wc作为它的标准输入。

    由于大多数命令都以参数的形式在命令行上指定输入文件的文件名,所以输入重定向并不经常使用。尽管如此,当要使用一个不接受文件名作为输入参数的命令,而需要的输入内容又存在一个文件里时,就能用输入重定向解决问题。

    3. 输出重定向

    输出重定向是指把命令(或可执行程序)的标准输出或标准错误输出重新定向到指定文件中。这样,该命令的输出就不显示在屏幕上,而是写入到指定文件中。

    输出重定向比输入重定向更常用,很多情况下都可以使用这种功能。例如,如果某个命令的输出很多,在屏幕上不能完全显示,那么将输出重定向到一个文件中,然后再用文本编辑器打开这个文件,就可以查看输出信息;如果想保存一个命令的输出,也可以使用这种方法。还有,输出重定向可以用于把一个命令的输出当作另一个命令的输入(还有一种更简单的方法,就是使用管道,将在下面介绍)。

    输出重定向的一般形式为:命令>文件名。例如:

    $ ls > directory.out

    $ cat directory.out

    ch1.doc ch2.doc ch3.doc chimp config mail/ test/

    $

    将ls命令的输出保存为一个名为directory.out的文件。

    注:如果>符号后边的文件已存在,那么这个文件将被重写。

    为避免输出重定向中指定文件只能存放当前命令的输出重定向的内容,shell提供了输出重定向的一种追加手段。输出追加重定向与输出重定向的功能非常相似,区别仅在于输出追加重定向的功能是把命令(或可执行程序)的输出结果追加到指定文件的最后,而该文件原有内容不被破坏。

    如果要将一条命令的输出结果追加到指定文件的后面,可以使用追加重定向操作符>>。形式为:命令>>文件名。例如:

    $ ls *.doc>>directory.out

    $ cat directory.out

    ch1.doc ch2.doc ch3.doc chimp config mail/ test/

    ch1.doc ch2.doc ch3.doc

    $

    和程序的标准输出重定向一样,程序的错误输出也可以重新定向。使用符号2>(或追加符号2>>)表示对错误输出设备重定向。例如下面的命令:

    $ ls /usr/tmp 2> err.file

    可在屏幕上看到程序的正常输出结果,但又将程序的任何错误信息送到文件err.file中,以备将来检查用。

    还可以使用另一个输出重定向操作符(&>)将标准输出和错误输出同时送到同一文件中。例如:

    $ ls /usr/tmp &> output.file

    利用重定向将命令组合在一起,可实现系统单个命令不能提供的新功能。例如使用下面的命令序列:

    $ ls /usr/bin > /tmp/dir

    $ wc –w < /tmp/dir

    459

    统计了/usr/bin目录下的文件个数。


    4. 管 道

    将一个程序或命令的输出作为另一个程序或命令的输入,有两种方法,一种是通过一个临时文件将两个命令或程序结合在一起,例如上个例子中的/tmp/dir文件将ls和wc命令联在一起;另一种是Linux所提供的管道功能。这种方法比前一种方法更好。

    管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中未使用输出重定向)。

    通过使用管道符“|”来建立一个管道行。用管道重写上面的例子:

    $ ls /usr/bin|wc -w

    1789

    再如:

    $ cat sample.txt|grep "High"|wc -l

    管道将cat命令(列出一个文件的内容)的输出送给grep命令。grep命令在输入里查找单词High,grep命令的输出则是所有包含单词High的行,这个输出又被送给wc命令,wc命令统计出输入中的行数。假设sample.txt文件的内容如下:

    Things to do today:

    Low:Go grocery shopping

    High:Return movie

    High:Clear level 3 in Alien vs. Predator

    Medium:Pick up clothes from dry cleaner

    那么该管道行的结果是2。



    (四) 在Bash中的操作  

    <1> 命令和文件名扩展特性

    Bash 命令行具有命令和文件名扩展特性。当输入一个还没完成的命令或文件名时,只需键入Tab键就能激活命令和文件名扩展特性,从而完成该命令的剩余输入。如果有多个命令或文件的前缀相同,Bash将响铃并等待用户输入足够的字符,以便选择唯一的命令或文件名,如果找到,系统将自动补齐搜索到的命令或文件名,用户按回车键后,系统将执行这条指令。例如:

    $ cat pre <Tab>

    $ cat preface

    Bash 也能列出当前目录下部分匹配的文件名来完成文件名扩展。如果键入Esc,然后键入?,shell将列出所有与输入的字符串相匹配的文件名。例如下例,在没有完成的输入后键入Esc ?,shell将列出所有与输入的字符串相匹配的字符串,然后shell回显命令行,根据列出的文件名,可以键入要输入的文件名或按下Tab键来完成文件名扩展。例如:



    <2>命令行编辑

    在Bash中可以对命令行进行编辑,以便用户在执行所键入的命令之前能够修改所键入的命令。如果在键入命令时出现拼写错误,只需在运行所键入的命令之前,使用编辑命令来纠正编辑错误,然后执行它,而不用重新输入整行命令。这个功能对以长路径文件名作参数的命令特别有用。

    命令行编辑操作

    功能

    Ctrl+b或左箭头键

    左移一个字符(移至前一个字符)

    Ctrl+f或右箭头键

    右移一个字符(移至后一个字符)

    Ctrl+a

    移至行首

    Ctrl+e

    移至行尾

    Esc b

    左移一个单词

    Esc f

    右移一个单词

    Del

    删除光标所在处的字符

    Ctrl+d

    删除光标所在处的字符

    BACKSPACE或Ctrl+h

    删除光标左边的字符

    Ctrl+k

    删除至行尾



    <3> 命令历史

    在Bash 中,history命令能够保存最近所执行的命令。这些命令的历史记录号从1开始,只有有限个命令可以被保存起来,最多500个,即 history命令的历史记录号缺省值为500。要查看最近执行的命令,只要键入history命令,然后键入回车键,最近执行过的命令即按先后顺序被显示出来(各条命令前的数字为历史记录号)。

    [例】

    $ history

    1 cp mydata today

    2 vi mydata

    3 mv mydata reports

    4 cd reports

    5 ls



    所有这些命令都被称为事件(event),一个事件表示一个操作已经发生,即一个命令已被执行。这些事件根据它们被执行的先后顺序用数字标识,这一标识称为历史事件号。最后执行的历史事件的事件号最大。每个事件都可由它的历史事件号或命令的初始字符或字符串等确定。

    利用history命令能够查询以前的事件,并可把它们显示到命令行上执行这一事件。最简便的方法就是利用上下箭头键,把先前的事件逐次显示到命令行。这个操作不需要运行history命令就可以执行。按动一下上箭头键,那么上一次执行的一个事件就将出现在命令行上,再按一下,上一次的前一事件又会出现在命令行上;按动一下下箭头键,将会使当前事件的下一事件出现在命令行上。

    Bash也可以通过键入Esc、Tab键来完成对历史事件的字符扩展。和标准命令行扩展特性一样,键入历史事件的部分字符串,然后键入Esc,再键入 Tab键,与刚才键入的字符串相匹配的历史事件将自动扩展并回显到命令行处。如果不止一个事件与输入的字符串相匹配,就会听到一声响铃,继续键入字符或字符串,shell将会唯一确定用户所要键入的历史事件。


    查询历史事件操作

    功能

    Ctrl+n或向下光标键

    移至历史事件列表中当前事件的下一历史事件

    Ctrl+p或向上光标键

    移至历史事件列表中当前事件的前一历史事件

    Esc <

    移至历史事件列表表首

    Esc >

    移至历史事件列表表尾


    历史事件被保存在一个文件中,文件名由变量HISTFILE指定。通常这个文件的缺省名是.bash_history。通过给变量HISTFILE赋值,可以指定新的文件名。

    [例】

    $ echo $HISTFILE

    /home/lisa/.bash_history

    $ HISTFILE=”/home/lisa/newhist”

    $ echo $HISTFILE

    /home/lisa/newhist

    以上操作先显示变量HISTFILE的值,然后赋予它新的值“/home/lisa/newhist”,以后所有的历史事件将被保存在newhist文件中。



    <4>别名

    还有一个使工作变得轻松的方法是使用命令别名。命令别名通常是其他命令的缩写,用来减少键盘输入。

    命令格式为:

    alias [alias-name=’original-command’]

    其中,alias-name是用户给命令取的别名,original-command是原来的命令和参数。需要注意的是,由于Bash是以空格或者回车来识别原来的命令的,所以如果不使用引号就可能导致Bash只截取第一个字,从而出现错误。如果alias命令后面不使用任何参数,则显示当前正在使用的被别名化的命令及其别名。为命令取的别名在该次登录期间始终有效。如果用户需要别名在每次登录时都有效,那么就将alias命令写到初始化脚本文件中。

    [例]如果经常要键入如下的命令,最好为它建立一个别名来减少工作量。

    $ cd /usr/X11/lib/X11

    假如为这个长命令建立一个名为goconfig的别名,在Bash提示符下键入如下命令:

    $ alias goconfig=’cd /usr/X11/lib/X11’

    现在,除非您退出Bash,键入goconfig将和原来的长命令有同样的作用。如果想取消别名,可以使用下面的命令:

    $ unalias goconfig

    这是一些很多人认为有用的别名,可以把它们写入初始化脚本文件中来提高工作效率:

    alias ll=’ls –l’

    alias log=’logout’

    alias ls=’ls –F’

    注意:在定义别名时,等号两边不能有空格,否则shell不能决定您需要做什么。仅在命令中包含空格或特殊字符时才需要引号。

    如果键入不带任何参数的alias命令,将显示所有已定义的别名。




    <5> 定制Bash
    用户可以将每次启动Bash所需要执行的命令放入初始化文件中,最常见的命令就是alias命令和变量定义两种。系统中的每个用户在其主目录中都有一个.bash_profile文件,Bash每次启动时都将读取该文件,其中包含的所有命令都将被执行。

    下面便是默认.bash_profile文件的代码:

    #.bash_profile

    #Get the aliases and functions

    if [-f ~/.bashrc ];then

    .~/.bashrc

    fi

    #User specific environment and startup programs

    PATH=$PATH:$HOME/bin

    ENV=$HOME/.bashrc

    USERNAME=””

    Export USERNAME ENV PATH
231/212>
Open Toolbar