chenery's profile小陈空间PhotosBlogListsMore ![]() | Help |
|
|
小陈空间态度决定一切!只要努力,就必定能成功!我相信我自己能行! August 29 MySQL优化实例【一】MySQL优化实例
在Apache, PHP, MySQL的体系架构中,MySQL对于性能的影响最大,也是关键的核心部分。对于Discuz!论坛程序也是如此,MySQL的设置是否合理优化,直接影响到论坛的速度和承载量!同时,MySQL也是优化难度最大的一个部分,不但需要理解一些MySQL专业知识,同时还需要长时间的观察统计并且根据经验进行判断,然后设置合理的参数。 下面我们了解一下MySQL优化的一些基础,MySQL的优化我分为两个部分,一是服务器物理硬件的优化;二是MySQL自身(my.cnf)的优化。 (1) 服务器硬件对MySQL性能的影响 a) 磁盘寻道能力(磁盘I/O),以目前高转速SCSI硬盘(7200转/秒)为例,这种硬盘理论上每秒寻道7200次,这是物理特性决定的,没有办法改变。MySQL每秒钟都在进行大量、复杂的查询操作,对磁盘的读写量可想而知。所以,通常认为磁盘I/O是制约MySQL性能的最大因素之一,对于日均访问量在100万PV以上的Discuz!论坛,由于磁盘I/O的制约,MySQL的性能会非常低下!解决这一制约因素可以考虑以下几种解决方案: 使用RAID-0+1磁盘阵列,注意不要尝试使用RAID-5,MySQL在RAID-5磁盘阵列上的效率不会像你期待的那样快; 抛弃传统的硬盘,使用速度更快的闪存式存储设备。经过Discuz!公司技术工程的测试,使用闪存式存储设备可比传统硬盘速度高出6-10倍左右。 b) CPU 对于MySQL应用,推荐使用S.M.P.架构的多路对称CPU,例如:可以使用两颗Intel Xeon 3.6GHz的CPU。 c) 物理内存对于一台使用MySQL的Database Server来说,服务器内存建议不要小于2GB,推荐使用4GB以上的物理内存。 (2) MySQL自身因素当解决了上述服务器硬件制约因素后,让我们看看MySQL自身的优化是如何操作的。对MySQL自身的优化主要是对其配置文件my.cnf中的各项参数进行优化调整。下面我们介绍一些对性能影响较大的参数。 由于my.cnf文件的优化设置是与服务器硬件配置息息相关的,因而我们指定一个假想的服务器硬件环境: CPU: 2颗Intel Xeon 2.4GHz 内存: 4GB DDR 硬盘: SCSI 73GB 下面,我们根据以上硬件配置结合一份已经优化好的my.cnf进行说明: # vi /etc/my.cnf 以下只列出my.cnf文件中[mysqld]段落中的内容,其他段落内容对MySQL运行性能影响甚微,因而姑且忽略。 [mysqld] port = 3306 serverid = 1 socket = /tmp/mysql.sock skip-locking # 避免MySQL的外部锁定,减少出错几率增强稳定性。 skip-name-resolve 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求! back_log = 384 指定MySQL可能的连接数量。当MySQL主线程在很短的时间内接收到非常多的连接请求,该参数生效,主线程花费很短的时间检查连接并且启动一个新线程。 back_log参数的值指出在MySQL暂时停止响应新请求之前的短时间内多少个请求可以被存在堆栈中。 如果系统在一个短时间内有很多连接,则需要增大该参数的值,该参数值指定到来的TCP/IP连接的侦听队列的大小。不同的操作系统在这个队列大小上有它自己的限制。 试图设定back_log高于你的操作系统的限制将是无效的。默认值为50。对于Linux系统推荐设置为小于512的整数。 key_buffer_size = 256M # key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。 查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 6 = 600MB。所以,对于内存在4GB左右的服务器推荐设置为6-8M。 read_buffer_size = 4M 读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享! join_buffer_size = 8M 联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享! myisam_sort_buffer_size = 64M
table_cache = 512
thread_cache_size = 64
query_cache_size = 64M
指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察: # > SHOW VARIABLES LIKE '%query_cache%'; # > SHOW STATUS LIKE 'Qcache%'; # 如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况; 如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。 tmp_table_size = 256M
max_connections = 768
指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提 示,则需要增大该参数值。 max_connect_errors = 10000000
wait_timeout = 10
指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。 thread_concurrency = 8 该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4 × 2 = 8 skip-networking 开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开启该选项!否则将无法正常连接! July 11 提高HTML代码的效率许多网站设计者最常犯的错误便是当其网页能够在IE下正常显示便认为其代码正确无误,甚至常看到有人在抱怨其网站排名不理想,到其网站简单看一下便可发现 HTML代码中充斥各种各样的错误,在那样的代码基础上无论付出多少努力去优化网站结果都可能是付诸流水的啊!事实上,IE是一款对HTML代码容错能力甚高的的浏览器,——说句题外话,尽管我们可以有各式各样的理由可以攻击微软,但微软对其产品操作的易手性及可用性方面所做的努力是不容抹杀的。——Web页面能够在IE下正常显示绝不意味着页面的HTML代码没有问题,甚至可以推而广之,Web页面在多种浏览器下均可正常显示也不意味着HTML代码完全合法有效,毕竟哪个浏览器都要保证基本的容错的功能,不然,就会发生即使仅仅因为网络传输中的一点导致导致 HTML页面显示不正常了,而这在网络带宽仍然紧张的今天仍是频繁发生的。 什么是合法有效的HTML代码 同其他语言一样,HTML也有自己的语法规则,无论是浏览器还是搜索引擎的Spider都在根据这些规则来分析网页代码中的内容。但很多时候,即使对熟练人员来说,在HTML页面构建时仍然难免出些HTML代码上的错误,更别提大部分所见即所得编辑器造成的HTML冗余臃肿问题了。 如果页面中不存在违背HTML标准语法规范的成分,即可被称为合法有效的HTML代码 合法有效的HTML代码对SEO的重要性 要使搜索引擎收录我们的网页,——在此基础上才能谈网站优化网站推广——其前提是要让搜索引擎的Spider能读懂我们的Web文件。搜索引擎 Spider阅读网页的根据便是HTML规范,通过对HTML代码的分析,Spider才能判断网页内容,在此基础上才能判断针对相应关键词的相关性。 需要明确的是,搜索引擎Spider不同于浏览器的一点便是其容错能力相对于浏览器要差不少,如果页面代码中存在其无法解释的HTML代码时,其便可能停止阅读该页面甚至可能停止在我们的网站内爬行,更严重的错误甚至会导致其同时也丢弃已经收集到的网站内其他页面的内容信息。 尽管如今如大主要搜索引擎也都在尽力提高Spider的容错能力,让其可以在HTML代码出现一般性错误时不至影响对内容的收集。但很多时候,仍然会发生如漏了一个关闭标签导致整个页面的内容被忽略的情况。 另一方面,合法有效的HTML也可以保证Web页面可以在多种浏览器下被正确解释,避免同一个页面在IE下显示正常在Mozilla下却严重变形的情况(当然,不能完全避免),这对于提高网站的可用性方面也是有着极大 好处的。 如何验证HTML代码的合法有效? Internet有很多类似的免费服务可以帮我们验证网页代码是否合法有效,其中最著名的即是 W3C HTMLValidator,这是由W3C( World Wide WebConsortium:万维网联盟)官方推出的免费服务项目,在其页面上只需输入待验证的HTML地址或者上传一个在本地机上的HTML文件即可,其会很快返回校验结果,是否无误,如有错误分别为哪些及如何改进等。 同时,W3C HTML Validator也提供对CSS文件的验证服务。 提高HTML代码的效率 前文我们提说过很多所见即所得编辑器造成的HTML冗余臃肿问题,这种情况在很多中文网站相当普遍。所见即所得编辑器如FrontPage、 Dreamweaver,尤其在其对一个网页进行修改的时候,往往会产生很多不必要的冗余代码。当页面的HTML文件在存在大量的冗余代码时,文件便会变得臃肿,这不但会降低网页的打开速度,损害到网页的效率,同时也会严重影响到相当网页的搜索引擎排名。 与其把精力投入到一定通过W3C认证上,个人认为,倒不如把更多的精力放到精减代码上,如引入CSS等,以实现代码的干净简洁。这样的优化效果会更明显。 榨干php 提高效率这篇杂文翻译整理自网络各路文档资料(见最末的参考资料),尤其是 Ilia Alshanetsky (佩服之至) 在多个 PHP 会议上的演讲,主要是各类提高 PHP 性能的技巧。为求精准,很多部分都有详细的效率数据,以及对应的版本等等。偷懒,数据就不一一给出了,直接给结论,如果需要看原文档,请到文末「参考资料」部分。橙色标题为推荐部分。 不要用常量代替字符串 不要把 count/strlen/sizeof 放到 for 循环的条件语句中 ============================================================================ 在进行大型系统的开发的时候,我总是困饶,是否应该包含每一个可能用到的类库文件。 ======================================================================== June 12 图片处理类/**
*名称:Image.class.php *作用:公共处理类 *说明: 功 能:利用PHP的GD库生成高质量的缩略图 运行环境:PHP5.01/GD2 类说明:可以选择是/否裁图。 如果裁图则生成的图的尺寸与您输入的一样。 原则:尽可能多保持原图完整 如果不裁图,则按照原图比例生成新图 原则:根据比例以输入的长或者宽为基准 参 数:$img:源图片地址 $wid:新图的宽度 $hei:新图的高度 $c:是否裁图,1为是,0为否 *版权: *作者: *时间:2005-4-23 **/ class Image
{ //图片类型 var $type; //实际宽度 var $width; //实际高度 var $height; //改变后的宽度 var $resize_width; //改变后的高度 var $resize_height; //是否裁图 var $cut; //源图象 var $srcimg; //目标图象地址 var $dstimg; //临时创建的图象 var $im; function Resize($img, $wid, $hei,$c, $dimg='')
{ $this->srcimg = $img; $this->resize_width = $wid; $this->resize_height = $hei; $this->cut = $c; //图片的类型 $this->type = strtolower(substr(strrchr($this->srcimg,"."),1)); //目标图象地址 $this->dstimg = ($dimg) ? $dimg.".".$this->type : $this->srcimg; //初始化图象 $this->initi_img(); $pic = getimagesize($this->srcimg); $this->width = $pic[0]; $this->height = $pic[1]; //生成图象 $this->newimg(); ImageDestroy ($this->im); } function newimg() { //改变后的图象的比例 $resize_ratio = ($this->resize_width)/($this->resize_height); //实际图象的比例 $ratio = ($this->width)/($this->height); if(($this->cut)=="1") //裁图 { if($ratio>=$resize_ratio) //高度优先 { $newimg = imagecreatetruecolor($this->resize_width,$this->resize_height); imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resize_width,$this->resize_height, (($this->height)*$resize_ratio), $this->height); ImageJpeg ($newimg,$this->dstimg); } if($ratio<$resize_ratio) //宽度优先 { $newimg = imagecreatetruecolor($this->resize_width,$this->resize_height); imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resize_width, $this->resize_height, $this->width, (($this->width)/$resize_ratio)); ImageJpeg ($newimg,$this->dstimg); } } else //不裁图 { if($ratio>=$resize_ratio) { $newimg = imagecreatetruecolor($this->resize_width,($this->resize_width)/$ratio); imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resize_width, ($this->resize_width)/$ratio, $this->width, $this->height); ImageJpeg ($newimg,$this->dstimg); } if($ratio<$resize_ratio) { $newimg = imagecreatetruecolor(($this->resize_height)*$ratio,$this->resize_height); imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, ($this->resize_height)*$ratio, $this->resize_height, $this->width, $this->height); ImageJpeg ($newimg,$this->dstimg); } } } //初始化图象 function initi_img() { if($this->type=="jpg") { $this->im = imagecreatefromjpeg($this->srcimg); } if($this->type=="gif") { $this->im = imagecreatefromgif($this->srcimg); } if($this->type=="png") { $this->im = imagecreatefrompng($this->srcimg); } } //返回:width="",height="" function DisplaySize($file,$w_size,$h_size) { if(file_exists($file)) { $image_size = getimagesize($file); if($w_size > $h_size) { //设定图像宽大于高
if($image_size[0] >= $image_size[1] && $image_size[0] >= $w_size) { if(($image_size[0]/$image_size[1])<=($w_size/$h_size)) { return("height=\"".$h_size."\""); } else { return("width=\"".$w_size."\""); } } if($image_size[0] < $image_size[1] && $image_size[1] >= $h_size) { return("height=\"".$h_size."\""); } if($image_size[0] <= $w_size && $image_size[1] <= $h_size) { return (""); } } elseif($w_size == $h_size) { //设定图像宽等于高 if($image_size[0] >= $image_size[1] && $image_size[0] >= $w_size) { return ("width=\"".$w_size."\""); } if($image_size[0] < $image_size[1] && $image_size[1] > $h_size) { return ("height=\"".$h_size."\""); } if($image_size[0] <= $w_size && $image_size[1] <= $h_size) { return (""); } } else { //设定图像宽小于高 if($image_size[1] >= $image_size[0] && $image_size[1] >= $h_size) { if(($image_size[0]/$image_size[1])<=($w_size/$h_size)) { return("height=\"".$h_size."\""); } else { return("width=\"".$w_size."\""); } } if($image_size[1] < $image_size[0] && $image_size[0] >= $w_size) { return("width=\"".$w_size."\""); } if($image_size[0] <= $w_size && $image_size[1] <= $h_size) { return (""); } } } } /**
* 图片水印方法 * 运行环境:PHP5.01/GD2 * 功能:把上传图片加上水印 * * */ var $groundImage; //上传的图片 var $groundImageWidth; //上传图片的宽 var $groundImageHeight; //上传图片的高 var $groundImageHandle; //上传图片的标识 var $waterType; //水印类型,0是文字,1是图片 var $waterPosType; //水印在图片的位置 var $waterPosX; //水印在图片中的X位置 var $waterPosY; //水印在图片中的Y位置 var $waterWidth; //水印图片的宽 var $waterHeight; //水印图片的高 var $waterImage; //水印图片 var $waterImageType; //水印图片的类型标记( = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM) var $waterImageHandle; //水印图片的类型标记 // var $waterImageAlpha; var $waterText; //水印文本 var $waterTextColor; //文本颜色 var $waterTextSize; //文本大小 var $waterTextFont; //文本字体 var $errorMsg; //错误信息 //设置图片水印,$groundImage 上传图片名;$waterPosType 在图片中的位置
function PhpUpImageWater($groundImage = "demo.jpg", $waterPosType = 0) { if(false == file_exists($groundImage)) { $this->throwError("groundImage404"); } $this->checkGD(); $this->groundImage = &$groundImage; $this->waterType = &$waterType; $this->waterPosType = &$waterPosType; $this->setGroundImageInfo(); } //检查GD库 function checkGD() { if(false == function_exists("gd_info")) { $this->throwError("NonGD"); } } //获得上传图片信息
function setGroundImageInfo() { $groundImageType = getimagesize($this->groundImage); $this->groundImageWidth = $groundImageType[0]; $this->groundImageHeight = $groundImageType[1]; $this->groundImageType = $groundImageType[2]; if($this->groundImageWidth < 150 or $this->groundImageHeight < 150) { $this->throwError("TooSmall"); } } //设置文字水印
function setWaterTextInfo($waterText = "phpup.com",$waterTextColor = "#000000", $waterTextSize = "5", $waterTextFont = "./couri.ttf") { $this->waterType = 0; if(strlen($waterTextColor) == 7) { $this->waterTextColor = &$waterTextColor; } else { $this->throwError("WrongColor"); } $this->waterText = &$waterText; $this->waterTextSize = &$waterTextSize; $this->waterTextFont = &$waterTextFont; $waterTextInfo = imagettfbbox(ceil($this->waterTextSize*1.2), 0, $this->waterTextFont, $this->waterText); $this->waterWidth = $waterTextInfo[4] - $waterTextInfo[6]; $this->waterHeight = $waterTextInfo[1] - $waterTextInfo[7]; unset($waterTextInfo); } //设置图片水印 function setWaterImageInfo($waterImage = "/server/www/tel168/tpl/images/shuiyin.png") { if(file_exists($waterImage)) { $this->waterType = 1; $this->waterImage = &$waterImage; $waterImageInfo = getimagesize($this->waterImage); $this->waterWidth = $waterImageInfo[0]; $this->waterHeight = $waterImageInfo[1]; $this->waterImageType = $waterImageInfo[2]; unset($waterImageInfo); } else { $this->throwError("waterImage404"); } } //设置水印在上传图片中的位置
function setWaterPos() { switch($this->waterPosType) { case 0://随机 $this->waterPosX = rand(0,($this->groundImageWidth - $this->waterWidth)); $this->waterPosY = rand(0,($this->groundImageHeight - $this->waterHeight)); break; case 1://1为顶端居左 $this->waterPosX = 0; $this->waterPosY = 0; break; case 2://2为顶端居中 $this->waterPosX = ($this->groundImageWidth - $this->waterWidth) / 2; $this->waterPosY = 0; break; case 3://3为顶端居右 $this->waterPosX = $this->groundImageWidth - $this->waterWidth; $this->waterPosY = 0; break; case 4://4为中部居左 $this->waterPosX = 0; $this->waterPosY = ($this->groundImageHeight - $this->waterHeight) / 2; break; case 5://5为中部居中 $this->waterPosX = ($this->groundImageWidth - $this->waterWidth) / 2; $this->waterPosY = ($this->groundImageHeight - $this->waterHeight) / 2; break; case 6://6为中部居右 $this->waterPosX = $this->groundImageWidth - $this->waterWidth; $this->waterPosY = ($this->groundImageHeight - $this->waterHeight) / 2; break; case 7://7为底端居左 $this->waterPosX = 0; $this->waterPosY = $this->groundImageHeight - $this->waterHeight * rand(115,125) / 100; break; case 8://8为底端居中 $this->waterPosX = ($this->groundImageWidth - $this->waterWidth) / 2; $this->waterPosY = $this->groundImageHeight - $this->waterHeight * rand(115,125) / 100; break; case 9://9为底端居右 $this->waterPosX = $this->groundImageWidth - $this->waterWidth; $this->waterPosY = $this->groundImageHeight - $this->waterHeight * rand(115,120) / 100; break; default://随机 $this->waterPosX = rand(0,($this->groundImageWidth - $this->waterWidth)); $this->waterPosY = rand(0,($this->groundImageHeight - $this->waterHeight)); } } function setGroundImageHandle() { switch($this->groundImageType) { case 1: $this->groundImageHandle = imagecreatefromgif($this->groundImage); break; case 2: $this->groundImageHandle = imagecreatefromjpeg($this->groundImage); break; case 3: $this->groundImageHandle = imagecreatefrompng($this->groundImage); break; default: $this->throwError("NonType"); } } function setWaterImageHandle()
{ switch($this->waterImageType) { case 1: $this->waterImageHandle = imagecreatefromgif($this->waterImage); break; case 2: $this->waterImageHandle = imagecreatefromjpeg($this->waterImage); break; case 3: $this->waterImageHandle = imagecreatefrompng($this->waterImage); break; default: $this->throwError("NonType"); } } //创建新图片
function putWateredImage($extFileName) { switch($this->groundImageType) { case 1: imagegif($this->groundImageHandle, $extFileName.$this->groundImage); break; case 2: imagejpeg($this->groundImageHandle, $extFileName.$this->groundImage); break; case 3: imagepng($this->groundImageHandle, $extFileName.$this->groundImage); break; default: $this->throwError("NonType"); } } //销毁图像 function destroyHandle() { imagedestroy($this->groundImageHandle); if(isset($this->waterImageHandle)) { imagedestroy($this->waterImageHandle); } } //生成水印图片 function makeWater($extFileName = "") { $this->setGroundImageHandle(); $this->setWaterPos(); imagealphablending($this->groundImageHandle, true); if($this->waterType == 0) { imagettftext($this->groundImageHandle, $this->waterTextSize, 0, $this->waterPosX, $this->waterHeight + $this->waterPosY, imagecolorallocate($this->groundImageHandle, hexdec(substr($this->waterTextColor,1,2)), hexdec(substr($this->waterTextColor,3,2)), hexdec(substr($this->waterTextColor,5,2))), $this->waterTextFont, $this->waterText); } else { $this->setWaterImageHandle(); imagecopy($this->groundImageHandle,$this->waterImageHandle , $this->waterPosX, $this->waterPosY, 0, 0, $this->waterWidth,$this->waterHeight); } @unlink($this->groundImage); $this->putWateredImage($extFileName); $this->destroyHandle(); } //异常模块
function throwError($errType) { switch($errType) { case "TooSmall": $this->errorMsg = "要打水印图片太小"; break; case "groundImage404": $this->errorMsg = "要打水印图片不存在"; break; case "waterImage404": $this->errorMsg = "水印图片不存在"; break; case "NonGD": $this->errorMsg = "没有安装GD库"; break; case "NonType": $this->errorMsg = "不支持的文件格式"; break; case "WrongColor": $this->errorMsg = "错误的颜色格式"; break; default: $this->errorMsg = "未知错误"; } die($this->errorMsg); exit(); } } SHELL自动备份脚本#!/bin/bash # #Role : Backup procedures #Note : Monday complete backup ,Tuesday to Sunday Incremental Backup #Parameter Description # Parameter 1:Backup directory name [Directory document addresses or Directory name] # Parameter 2:Backup level [0:Backup database and Web 1:Backup Web 2:Backup database] #Original Author: Hongbin.Chen <chenunix@gmail.com> backup_run () { [ -d "$1" ] || return 0 file_dir="$1" backup_dir="$2/`date +%G%m`/" [ -d "$backup_dir" ]|| mkdir -p "$backup_dir" DAT=`date | awk '{print $1}'` if [ $DAT = 'Mon' ] then filename="`date +%d`.tar.gz" [ -f $backup_dir$filename ] || tar cvfz $backup_dir$filename $file_dir else filename="`date +%d`.tar.gz" t1=`date +%d` t2=`expr $t1 - 1 ` yesterday=`date +%Y\/%m\/`$t2 tar -cvz -N "$yesterday" -f $backup_dir$filename $file_dir fi } backupDir="/server/backup" webDir="/server/www" dataDir="/server/soft/mysql/data" if [ -f "$1" ] then while read line; do if [ ! -n "$2" ] || [ "$2" = "0" ] then [ -d "$webDir/$line" ] && backup_run "$webDir/$line" "$backupDir/web/$line" [ -d "$dataDir/$line" ] && backup_run "$dataDir/$line" "$backupDir/data/$line" elif [ "$2" = "1" ] then [ -d "$webDir/$line" ] && backup_run "$webDir/$line" "$backupDir/web/$line" elif [ "$2" = "2" ] then [ -d "$dataDir/$line" ] && backup_run "$dataDir/$line" "$backupDir/data/$line" fi done < $1 elif [ -n "$1" ] then if [ ! -n "$2" ] || [ "$2" = "0" ] then [ -d "$webDir/$1" ] && backup_run "$webDir/$1" "$backupDir/web/$1" [ -d "$dataDir/$1" ] && backup_run "$dataDir/$1" "$backupDir/data/$1" elif [ "$2" = "1" ] then [ -d "$webDir/$line" ] && backup_run "$webDir/$1" "$backupDir/web/$1" elif [ "$2" = "2" ] then [ -d "$dataDir/$line" ] && backup_run "$dataDir/$1" "$backupDir/data/$1" fi else backup_run "$webDir" "$backupDir/web" backup_run "$dataDir" "$backupDir/data" fi |
|
||||
|
|