[转]Linux系统Shell程序设计的流程控制

和其他高级程序设计语言一样,Shell提供了用来控制程序执行流程的命令,包括条件分支和循环结构,用户可以用这些命令创建非常复杂的程序。

  与传统语言不同的是,Shell用于指定条件值的不是布尔运算式,而是命令和字串。

  1.测试命令

  test命令用于检查某个条件是否成立,它可以进行数值、字符和文件3个方面的测试,其测试符和相应的功能分别如下。

  (1)数值测试:

  -eq 等于则为真。

  -ne 不等于则为真。

  -gt 大于则为真。

  -ge 大于等于则为真。

  -lt 小于则为真。

  -le 小于等于则为真。

  (2)字串测试:

  = 等于则为真。

  != 不相等则为真。

  -z字串 字串长度伪则为真。

  -n字串 字串长度不伪则为真。

  (3)文件测试:

  -e文件名 如果文件存在则为真。

  -r文件名 如果文件存在且可读则为真。

  -w文件名 如果文件存在且可写则为真。

  -x文件名 如果文件存在且可执行则为真。

  -s文件名 如果文件存在且至少有一个字符则为真。

  -d文件名 如果文件存在且为目录则为真。

  -f文件名 如果文件存在且为普通文件则为真。

  -c文件名 如果文件存在且为字符型特殊文件则为真。

  -b文件名 如果文件存在且为块特殊文件则为真。

  另外,Linux还提供了与(!)、或(-o)、非(-a)三个逻辑操作符,用于将测试条件连接起来,其优先顺序为:!最高,-a次之,-o最低。

  同时,bash也能完成简单的算术运算,格式如下:

  $[expression]

  例如:

  var1=2

  var2=$[var1*10+1]

  则var2的值为21。

  2.if条件语句

  Shell程序中的条件分支是通过if条件语句来实现的,其一般格式为:

  if 条件命令串

  then

  条件为真时的命令串

  else

  条件为假时的命令串

  fi

  3.for循环

  for循环对一个变量的可能的值都执行一个命令序列。赋给变量的几个数值既可以在程序内以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。for循环的一般格式为:

  for变量名    [in数值列表]

  do

  若干个命令行

  done

  变量名可以是用户选择的任何字串,如果变量名是var,则在in之后给出的数值将顺序替换循环命令列表中的$var。如果省略了in,则变量var的取值将是位置参数。对变量的每一个可能的赋值都将执行do和done之间的命令列表。

  4.while和until循环

  while和until命令都是用命令的返回状态值来控制循环的。While循环的一般格式为:

  while

  若干个命令行1

  do

  若干个命令行2

  done

  只要while的“若干个命令行1”中最后一个命令的返回状态为真,while循环就继续执行do…done之间的“若干个命令行2”。

  until命令是另一种循环结构,它和while命令相似,其格式如下:

  until

   若干个命令行1

  do

   若干个命令行2

  done

  until循环和while循环的区别在于:while循环在条件为真时继续执行循环,而until则是在条件为假时继续执行循环。

  Shell还提供了true和false两条命令用于创建无限循环结构,它们的返回状态分别是总为0或总为非0。

  5.case条件选择

  if条件语句用于在两个选项中选定一项,而case条件选择为用户提供了根据字串或变量的值从多个选项中选择一项的方法,其格式如下:

  case string in

  exp-1)

  若干个命令行1

  ;;

  exp-2)

   若干个命令行2

  ;;

  ……

  *)

  其他命令行

  esac

  Shell通过计算字串string的值,将其结果依次和运算式exp-1, exp-2等进行比较,直到找到一个匹配的运算式为止。如果找到了匹配项,则执行它下面的命令直到遇到一对分号(;;)为止。

  在case运算式中也可以使用Shell的通配符(“*”、“?”、“[ ]”)。通常用 * 作为case命令的最后运算式以便在前面找不到任何相应的匹配项时执行“其他命令行”的命令。

  6.无条件控制语句break和continue

  break用于立即终止当前循环的执行,而contiune用于不执行循环中后面的语句而立即开始下一个循环的执行。这两个语句只有放在do和done之间才有效。

  7.函数定义

  在Shell中还可以定义函数。函数实际上也是由若干条Shell命令组成的,因此它与Shell程序形式上是相似的,不同的是它不是一个单独的进程,而是Shell程序的一部分。函数定义的基本格式为:

  functionname

  {

   若干命令行

  }

  调用函数的格式为:

  functionname param1 param2…

  Shell函数可以完成某些例行的工作,而且还可以有自己的退出状态,因此函数也可以作为if, while等控制结构的条件。

  在函数定义时不用带参数说明,但在调用函数时可以带有参数,此时Shell将把这些参数分别赋予相应的位置参数$1, $2, …及$*。

  8.命令分组

   在Shell中有两种命令分组的方法:()和{}。前者当Shell执行()中的命令时将再创建一个新的子进程,然后这个子进程去执行圆括弧中的命令。 当用户在执行某个命令时不想让命令运行时对状态集合(如位置参数、环境变量、当前工作目录等)的改变影响到下面语句的执行时,就应该把这些命令放在圆括弧 中,这样就能保证所有的改变只对子进程产生影响,而父进程不受任何干扰。{}用于将顺序执行的命令的输出结果用于另一个命令的输入(管道方式)。当我们要 真正使用圆括弧和花括弧时(如计算运算式的优先顺序),则需要在其前面加上转义符()以便让Shell知道它们不是用于命令执行的控制所用。

  9.信号

  trap命令用于在Shell程序中捕捉信号,之后可以有3种反应方式:

  (1)执行一段程序来处理这一信号。

  (2)接受信号的默认操作。

  (3)忽视这一信号。

  trap对上面3种方式提供了3种基本形式:

  第一种形式的trap命令在Shell接收到与signal list清单中数值相同的信号时,将执行双引号中的命令串。

  trap ‘commands’ signal-list

  trap "commands" signal-list

  为了恢复信号的默认操作,使用第二种形式的trap命令:

  trap signal-list

  第三种形式的trap命令允许忽略信号:

  trap " " signal-list

  注意:

  (1)对信号11(段违例)不能捕捉,因为Shell本身需要捕捉该信号去进行内存的转储。

  (2)在trap中可以定义对信号0的处理(实际上没有这个信号),Shell程序在其终止(如执行exit语句)时发出该信号。

  (3)在捕捉到signal-list中指定的信号并执行完相应的命令之后,如果这些命令没有将Shell程序终止的话,Shell程序将继续执行收到信号时所执行的命令后面的命令,这样将很容易导致Shell程序无法终止。

   另外,在trap语句中,单引号和双引号是不同的。当Shell程序第一次碰到trap语句时,将把commands中的命令扫描一遍。此时若 commands是用单引号括起来的话,那么Shell不会对commands中的变量和命令进行替换,否则commands中的变量和命令将用当时具体 的值来替换。

Read: 682

史记与孙子兵法

    《史记》与《孙子兵法》的关系非常密切,《孙子·吴起列传》是《史记》的重要一篇,太史公是为中国古代最伟大的军事家孙子立传的第一人,孙武的生平也是通过《史记》第一次被载入史册。

一、《史记》与《孙子兵法》的名称

    《史记》的《孙子·吴起列传》并没有明确提出《孙子兵法》。“孫臏以此名顯天下,世傳其兵法”二句,也没有说“兵法”之名就是《孙子兵法》。《史记·卫将军骠骑列传》:“天子尝欲教之《孙吴兵法》,对曰:顾方略何如耳,不至学古兵法(当含《孙子兵法》等)。”所以,《史记》并未明言《孙子兵法》,而只有《孙吴兵法》之称;而《孙吴兵法》应当是《孙子、吴起兵法》的合本。

《史记》的《孙子吴起列传》:“太史公曰:世俗所稱師旅,皆道《孫子十三篇》《吳起兵法》;据此可知,《史记孙子吴起列传》是以《孙子十三篇》作为《孙子兵法》的称名。

    《汉书·东方朔传》东方朔自称学过兵法时,也说“学《孙吴兵法》战阵之具,鼓之教。”可见,东方朔学的《孙子兵法》也是孙子、吴起兵法的合订本。

   《汉书·艺文志》明确记载的是《吴孙子兵法八十二篇》,可见,《孙子兵法》在汉代确实单独流传;但《汉志》前冠了“吴”字,是为了区别于《齐孙子八十九篇》。

    可见,在司马迁写作《史记》之时,更多流传的应当是《孙吴兵法》。

    《后汉书·礼仪志》、《舆服志》使用的也是《孙吴兵法》,可见,南朝刘宋时期《孙吴兵法》仍然相当流行。

    《后汉书·冯异传》:“好读书,通《左氏春秋》《孙子兵法》。注:孙子名武,善用兵,王阖庐之将也,作兵法十三篇,见《史》。”《孙子兵法》之名《汉志》有载,而《汉志》缘于刘歆《七略》,可见,《孙子兵法》与《孙吴兵法》在西汉都有流传,即既有单本又有合本。

   

二、《史记》中的战争描写与《孙子兵法》

   《史记》中描写了许多著名的战争,这些战争对《孙子兵法》有继承也有补充。

    1、巨鹿之战——投之亡地然后存,陷之死地然后生

    《项羽本纪》中的巨鹿之战是非常有名的一场战争。巨鹿之战中最有名的是如下一段:“项羽悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。”这就“破釜沉舟”

     项羽的这种作战方法即是《孙子兵法·九地》中“投之亡地然后存,陷之死地然后生。夫众陷于害,然后能为胜败”的应用。不过,项羽将其运得非常灵活而已。

    《汉志》中有《项王》一篇,此书今已失传,可见,项羽是深通兵法之人。他不仅会打仗,而且有《兵法》传世。此书可能是后人追记,但是,它证明了项羽的兵学修养极高。项羽年轻时,一定要学“万人敌”的兵法;所以,他才有如此高的兵学修养。

    2、彭城之战——攻其无备,出其不意

   《孙子兵法·始计》载:“攻其无备,出其不意。”项羽深谙此道,最著名的战例就是彭城之战。这是一场在中国军事史上以少胜多的著名战例。

    汉二年(前205)四月,刘邦利用项羽陷入山东战场平定齐地叛乱的机会,率领五十六万大军占领了西楚国都城的彭城。

    刘邦此行,主要是为了消灭项羽集团,顺便接走家人。刘邦起兵反秦时并没有携带家属,所以,他这次打到彭城,离他的老家沛县只有二百里地,所以,他想这次接走他的父亲、妻子、儿子、女儿。

    项羽得知刘邦攻占彭城的消息之后,带了三万精锐骑兵,绕过刘邦重点设防的彭城东面和北面,插到彭城之西的萧县,也就是今天安徽省的萧县。萧县在彭城的西面,距当时的彭城只有六十里地。项羽到达萧县之后,对攻占彭城的刘邦发动突然袭击。

    刘邦进入彭城之后,忙于搜刮项羽的财宝、美女,每天饮酒宴会,根本顾不上接他的家人。项羽从彭城之西,突然袭击彭城的汉军。战斗从早晨打响,到中午,楚军已经打败了汉军。

    项羽这次彭城之战只投入了三万军队,刘邦却有五十六万军队,为什么项羽能以如此少的军队大败刘邦呢?

    刘邦进了彭城,自以为已经稳操胜券,每天喝酒庆功,把当年项羽从长安掠走的秦朝的财宝、美女全都收归己有。这恰好应验了范增当年对刘邦的两句评价:贪于财 货,好美姬。他对项羽的反攻也有准备,但是,项羽却没有在刘邦重兵布防的彭城的北面、东面采取军事行动,而是,从彭城西面的萧县进行奇兵突袭,打了刘邦一 个措手不及,连刘邦本人也在一场突然而来的沙尘暴中侥幸逃生:

    围汉王三匝。于是,大风西北而起,折木发屋,扬沙石,窈冥昼晦。逢迎楚军,楚军大乱坏散,而汉王乃得与数十骑遁去。欲过沛收家室而西,楚亦使人追之沛,取汉王家。家皆亡,不与汉王相见。

    刘邦在前面逃,楚军在后面紧追不舍。刘邦在逃命中意外地遇见他的儿子、女儿,他的儿子是后来的汉惠帝,他的女儿是鲁元公主。为刘邦赶车的夏侯婴匆忙中将刘 邦的儿子、女儿抱上了车,但是,楚兵追得太急。刘邦担心因为车上多了儿子、女儿跑得慢,便一脚把儿子、女儿踹下车来。夏侯婴一见,赶快停车抱孩子,刘邦还 很不愿意。跑不远,刘邦又一脚把儿子、女儿踹下车来,夏侯婴又忙着停车抱孩子。一连几次这样,刘邦急得要拔剑杀夏侯婴。夏侯婴说:情况再紧急也不能不顾孩 子。刘邦这才同意让儿子、女儿跟他一块儿逃,最终摆脱了危险。可见,刘邦败得多么惨痛。

    项羽在彭城之战中大败刘邦,原因颇多。其中,非常重要的一个原因是“攻其不备,出其不意”。

    刘邦不是没有防备项羽,只是他防范的重点是彭城之东与彭城之北,因此,这是项羽从齐地进攻彭城最有可能性的方向;但是,项羽偏偏选择了彭城之西。这是刘邦最不设防的地方,所以,打了刘邦一个措手不及。

    3、韩信与龙且的对决——《孙子·始计》:故能而示之不能,用而示之不用,近而示之远,远而示之近。

    在楚汉战争中另一位军事天才是韩信,韩信成功的战例非常之多,我只举一个例子:

    韩信在灭掉魏、代、赵、燕诸国之后,兵临齐国,他在游士蒯通的劝告下,不顾刘邦已派郦食其已劝降齐王的现实,突然袭击,打进齐国。齐王杀郦食其,向项羽求救。齐地是西楚国国都彭城的北方大门,项羽在韩信横扫北方诸侯各国时几乎毫无作为,此时却派大将龙且率兵救齐。

    龙且是项羽集团的重要军事将领,《史记·陈丞相世家》记述了陈平劝刘邦施行反间计以击败项羽时曾经说过的一段非常重要的话:彼项王骨鲠之臣亚夫、钟离昧、龙且、周殷之属,不过数人耳

    陈平曾经在项羽手下做过官,后来畏罪投靠刘邦,因此,陈平非常熟悉项羽最重要的武将谋臣。在陈平开列的项羽手下的骨鲠之臣中就有龙且,由此可见,龙且在项羽集团中举足轻重的地位。

    龙且是项羽起兵反秦时就追随项南征北战的猛将,而且每到关键时刻项羽都会起用龙且。刘邦、项羽的第一次正面交手是彭城大战。此时是汉二年(前205)。

彭城之战失败而归的刘邦,并未就此罢手,而是思前想后,图谋灭项大计。刘邦此时提出了一个还有战略性的目标——联手灭项。他问张良:我愿意捐出函谷关以东 的土地,与人共分天下,谁是可以承担此重任的人?张良回答:只有三个人,一个是你手下的韩信,一个是三不管的彭越,一个是项羽手下的勇将黥布。

    刘邦立即派人策反了黥布。黥布是项羽手下的悍将,为项羽多次立过大功。黥布叛变使项羽非常恼火,项羽派出去平定黥布叛乱的大将就是龙且。

    黥布是著名悍将,汉十一年,刘邦抱病平黥布叛乱,其时项羽已死去六年,但是,刘邦看见黥布的军阵如同项羽的军阵还非常胆怯。此仗虽然刘邦取得最后胜利,可 是黥布的军威仍然为刘邦所重。刘邦尽管病得非常重,还不得不抱病出征,派谁去平黥布之乱他都不放心。为什么呢?黥布太有才了!可是,当年黥布背叛项羽之 时,项羽派去平定黥布之乱的却是龙且。龙且在项羽心中的地位由此可见一斑。

    龙且去平定黥布之乱的结果如何呢?《史记·黥布列传》有一段非常翔实的记载:

    布曰:如使者教,因起兵而击之耳。於是杀使者,因起兵而攻楚。楚使项声、龙且攻淮南,项王留而攻下邑。数月,龙且击淮南,破布军。布欲引兵走汉,恐楚王杀之,故间行与何俱归汉。

    龙且仅仅用了几个月的时间就平定了黥布之乱!黥布是悍将,连刘邦都怯他三分,可是龙且竟然打败了黥布。这说明什么?说明龙且深得项羽信任,说明龙且比黥布更高明,更凶悍。龙且的军事才能由此可见。

    在长达四年之久的楚汉战争之中,龙且被《史记》记载下来的并不多,其中,最为翔实的只有一次:韩信攻占齐地之后,项羽派龙且率兵救齐。

刘邦最后在军事上打败项羽的最大优势就是他手下的韩信攻占了黄河以北的全部地盘,灭掉了魏国、代国、赵国、燕国、齐国。特别是韩信破齐,对项羽的震憾最大!

    项羽一向非常重视齐地(今山东一带),当年齐地田氏与关中刘邦几乎同时造反,但是,项羽弃刘邦而攻田氏即是一例明证。因为齐地接靠彭城,齐地对西楚国的威 胁比起关中的刘邦要大得多。所以,韩信拿下魏、代、赵、燕诸国,项羽都未及时应对。韩信拿下了齐地,立即引起项羽的高度重视。

    项羽的第一个反应就是派龙且率兵救齐。龙且临危受命,说明了他在项羽心中的地位仍然是男一号。

    龙且到达齐地之后,与齐王田广合军一处。龙且带了多少军队,史书记载是“号称二十万”。据我估计,龙且所带军队应当是十万,而且是项羽从荥阳战场上抽调的 十万精兵。项羽与刘邦在荥阳对峙的二十八个月里,始终占有上风,其中一个重要原因是项羽的兵力从未少于刘邦。但是,汉四年刘邦最后追杀向今安徽撤退的项羽 军队时,刘邦是二十万军队,项羽只有十万军队。项羽的军队为什么越打越少,其中一个重要原因应当是龙且带走了项羽的十万精兵。这可是项羽的看家本钱啊!连 这种本钱项羽都舍得投资,可见,项羽对收复齐地何等重视。

    龙且是西楚国的悍将,十分善战。龙且到了齐地,有人向他建议:韩信的军队是远道而来的胜利之师,军锋正盛;我们是本土作战,应当深壁坚守,然后让齐王田广 到各地宣传齐王尚在,这样,各地被韩信征服的齐城就会倒戈反汉。韩信远道而来,如果齐地都倒戈反汉,韩信的军粮都很难解决。到了汉兵断粮之日,岂不是不战 而降汉军吗?

    战未合,人或说龙且曰:汉兵远斗穷战,其锋不可当。齐、楚自居其地战兵易败散;不如深壁,令齐王使其信臣,招所亡城。亡城闻其王在,楚来救,必反汉。汉兵二千里客居,齐城皆反之,其势无所得食,可无战而降也。

应当说,这是一个非常有远见的计谋,但是,龙且听不进去。龙且是项羽手下第一悍将,他击败过悍将黥布,从未打过败仗,更没有用计谋打败过敌人。龙且从来都 是在进攻战、遭遇战中打败对手的。因此,龙且认为:如果这样战胜韩信,岂不太丢面子了。更要命的是,龙且认为韩信非常容易打败。这一仗如果打胜,整个齐地 可得其半,于是,决定迎战韩信(龙且曰:吾平生知韩信为人易与耳!且夫救齐不战齐不战而降之,吾何功?今战而胜之,齐之半可得,何为止?遂战,与信夹潍水阵)。

    结果,在面对韩信大军之时,韩信巧妙地利用了龙且的骄傲自大,率军半渡潍水,假装力怯而退。龙且不知是计,遂带领少数军队渡潍水追杀。其实,韩信前一天晚 上已经派人在潍水上游用上万沙袋堵塞潍水。龙且不知深浅,自以为韩信怯懦,潍水水浅。等龙且渡过潍水,韩信立即派人将上游的万余沙袋全部撤掉。汹涌澎湃的 潍水滔滔而下,将龙且的军队切为两半,龙且的大部队因此渡不了河。渡过河的龙且,只带有少量军队,韩信率大军急围龙且,龙且最终战败被杀。龙且之死在情理 之中。龙且只不过用自己的生命验证了兵法中最普通的一条真理:骄兵必败。(韩信乃夜令人为万余囊,满盛沙,壅水上流,引军半渡,周龙且,佯不胜,还走。龙且果喜曰:固知信怯也。遂追信,渡水。信使人决壅囊,水大至,龙且军大半不得渡,即急击杀龙且水东,军散走——《史记·淮阴侯列传》

   但是,龙且之死却给项羽带来了致命一击:不仅彻底失去了齐地,使西楚国的国都完全暴露在汉兵的视野之下,而且使项羽二十八个月的荥阳对峙立即变得毫无意 义了。荥阳对峙的前提是西楚国的后方彭城是安全的,项羽军粮军需的保障地是安全的。齐地被韩信占领,项羽的大后方立即变得岌岌可危,再在荥阳对峙下去可能 面临被包围的险境与断粮的危险。所以,龙且的大意轻敌,不仅使自己失去了生命,也最终断送了项羽的霸业。龙且兵败被杀之日,也就是项羽大势已去之日。

韩信打败龙且的这一战法就是未敌以弱,即《孙子·始计》:故能而示之不能,用而示之不用,近而示之远,远而示之近。

    韩信是一位示弱的高手,几乎每战均用此法。井陉之战,韩信也用此计,示赵以弱,伪装战败,丢弃旗鼓,引得赵兵队形大乱,争抢旗鼓,再回马一枪,打败赵兵。

三、慎战         

    《孙子兵法·作战》篇对用兵之祸,有详细阐述:“凡用兵之法,驰车千驷,革车千乘,带甲十万,千里馈粮。则内外之费,宾客之用,胶漆之材,车甲之奉,日费千金,然后十万之师举矣。”可见,用十万之师费用之大。

    “善用兵者,役不再籍,粮不三载,取用于国,因粮于敌,故军食可足也。国之贫于师者远输,远输则百姓贫;近师者贵卖,贵卖则百姓财竭,财竭则急于丘役。力屈中原、内虚于家,百姓之费,十去其七;公家之费,破军罢马,甲胄矢弓,戟盾矛橹,丘牛大车,十去其六。”

    这是《孙子兵法》中非常精彩的一段论述:这段论述的核心是慎战。战争对财力的消耗太大,对百姓的伤害太大。《史记》中司马迁多次表述了这种慎战思想,其中,最主要是在有关对匈作战的记述之中。

《韩长孺列传》中记述了韩安國在朝议中反对用兵匈奴的意见曰:“千里而战,兵不获利”。

   《酷吏列传》中记载了博士狄山的悲剧。狄山反对用兵匈奴:“景帝不言兵,天下富實。今自陛下舉兵擊匈奴,中國已空虛,邉民大困貧,由此觀之,不如和親。”狄山因此而丧命。

    但是,司马迁在《史记》诸篇中不厌其烦地记载反对用兵的意见,这固然是历史的真实记载,但是,其中亦不乏慎兵之义。

    《平津侯主父列传》记载了主父偃初见武帝时的一番对话,

    所言九事,其八事为律令,一事谏伐匈奴。其辞曰:臣闻明主不恶切谏以博观,忠臣不敢避重诛以直谏,是故事无遗策而功流万世。今臣不敢隐忠避死以效愚计,愿陛下幸赦而少察之。《司马法》曰:国虽大,好战必亡;天下虽平,忘战必危。天下既平,天子大凯,春mì),诸侯春振旅,秋治兵,所以不忘战也。且夫怒者逆德也,兵者凶器也,争者末节也。古之人君,一怒必伏尸流血,故圣王重行之。夫务战胜穷武事者,未有不悔者也。

    昔秦皇帝任战胜之威,蚕食天下,并吞战国,海内一。功齐三代,务胜不休,欲攻匈奴,李斯谏曰:不可! 夫匈奴无城郭之居,委稷积之守,迁徙鸟举,难得而制也。轻兵深入,粮食必绝。踵粮以行,重不及事。得其地不足以为利也,遇其民不可役而守也。胜必杀之,非 民父母也。靡敝中国,快心匈奴,非长策也。秦皇帝不听,遂使蒙恬将兵攻胡,辟地千里,以河为境。地固泽鹹鹵,不生五谷。然後发天下丁男,以守北河。暴兵露师,十有余年,死者不可胜数。终不能逾河而北,是岂人众不足,兵草不备哉?其势不可也。又使天下蜚刍粟起於东,琅邪负海之郡,转轮北河。率三十锺而致一石。男子疾耕,不足於粮;女子纺绩,不足於帷幕。百姓靡敝,孤寡老弱,不能相养。道路死者相望,盖天下始畔秦也。

及至高皇帝,定天下略地於边,闻匈奴聚於代谷之外,而欲击之。御史成进谏曰:不可!夫匈奴之性,兽聚而鸟散,从之如搏影。今以陛下盛德,攻匈奴,臣窃危之。高帝不听,遂北至於代谷,果有平城之围。高皇帝盖悔之甚,乃使刘敬往结和亲之约,然後天下忘干戈之事。

   故《兵法》曰:兴师十万,日费千金。夫秦常积众,暴兵数十万人,虽有覆军杀将系虏单于之功,亦适足以结怨深仇,不足以偿天下之费。夫上虚府库,下敝百姓, 甘心於外国,非完事也。夫匈奴难得而制,非一世也。行盗侵驱,所以为业也。天性固然,上及虞夏殷周,固弗程督,禽兽畜之不属为人。夫上不观虞夏殷周之统, 而下修近世之失,此臣之所大忧,百姓之所疾苦也。且夫兵久则变生事苦,则虑易乃使边境之民靡敝愁苦,而有离心。将吏相疑而外市。故尉佗、章邯,得以成其私 也。夫秦政之所以不行者,权分乎二子,此得失之效也。故《周书》曰:安危在出令,存亡在所用。愿陛下详察之,少加意而熟虑焉。

     主父偃的话非直接引用《孙子兵法》,而是,引了《司马法》

     但是《孙子兵法·用间》也讲了同样的道理:

    孙子曰:凡兴师十万,出征千里,百姓之费,公家之奉,日费千金。内外骚动,怠於道路,不得操事者七十万家。相守数年,以一日之胜,而爱爵禄百金,不知敌之情者。不仁之至也。非人之将也,非主之佐也,非胜之主也。

主父偃上书九条,有关对匈作战的仅有一条,但是,司马迁独独对这一条详加记述,为什么?

    因为这一条主要是讲慎战。司马迁对此记述得如此详细,正说明司马迁对对匈作战持慎重态度。

   春秋战国至西汉时期是中国兵书产生最多的时期,但是,《汉书·艺文志》记载的许多兵书,如《项王》、《韩信》、《范蠡》等,但是,这些兵书今已全部失传。唯独《孙子兵法》流传至今,这是历史的选择,是优胜劣汰的结果。

四、对匈作战与创新发展——“出其不意,攻其不备”的新解

    汉武帝时期,最大的战争是对匈奴作战。但是,由于这场战争是农耕民族对草原民族的战争,因此,“长途奔袭,寻机作战”成为最适用的战争。当然,“长途奔 袭,寻机作战”也是“出其不意,攻其不备”;可是,这种“出其不意,攻其不备”与《孙子兵法》中讲的“出其不意,攻其不备”已经有了很大的区别。

    这是武帝时期对匈作战的需要,这是新的战争对《孙子兵法》的新要求。《史记》忠实记载了这种变化,适应这种新打法的卫青、霍去病等一批新的将军非常适应。李广等老一批将军却因为不适应这种新的战争方法而被淘汰出局。

    可见,现实在变化,战争也在变化,兵法也要适应这种变化而变化。经典的价值是永久性,但是,经典也需要创新,也需要发展。

Read: 781

[转] 榨干 PHP,提高效率

原文地址:http://www.phpchina.com/bbs/thread-13409-1-1.html

这篇杂文翻译整理自网络各路文档资料(见最末的参考资料),尤其是 Ilia Alshanetsky (佩服之至) 在多个 PHP 会议上的演讲,主要是各类提高 PHP 性能的技巧。为求精准,很多部分都有详细的效率数据,以及对应的版本等等。偷懒,数据就不一一给出了,直接给结论,如果需要看原文档,请到文末「参考资料」部分。橙色标题为推荐部分。

========================================================

静态调用的成员一定要定义成 static   (PHP5 ONLY)

贴士:PHP 5 引入了静态成员的概念,作用和 PHP 4 的函数内部静态变量一致,但前者是作为类的成员来使用。静态变量和 Ruby 的类变量(class variable)差不多,所有类的实例共享同一个静态变量。

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
class foo {
     function
bar() {
         echo
‘foobar’;
     }
}

$foo = new foo;

// instance way

$foo->bar();

// static way

foo::bar();
?>

静态地调用非 static 成员,效率会比静态地调用 static 成员慢 50-60%。主要是因为前者会产生 E_STRICT 警告,内部也需要做转换。

使用类常量 (PHP5 ONLY)

贴士:PHP 5 新功能,类似于 C++ 的 const。

使用类常量的好处是:

– 编译时解析,没有额外开销
– 杂凑表更小,所以内部查找更快
– 类常量仅存在于特定「命名空间」,所以杂凑名更短
– 代码更干净,使除错更方便

(暂时)不要使用 require/include_once

require/include_once 每次被调用的时候都会打开目标文件!

– 如果用绝对路径的话,PHP 5.2/6.0 不存在这个问题
– 新版的 APC 缓存系统已经解决这个问题

文件 I/O 增加 => 效率降低

如果需要,可以自行检查文件是否已被 require/include。

不要调用毫无意义的函数

有对应的常量的时候,不要使用函数。

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
php_uname
(‘s’) == PHP_OS;
php_version() == PHP_VERSION;
php_sapi_name() == PHP_SAPI;
?>

虽然使用不多,但是效率提升大概在 3500% 左右。

最快的 Win32 检查

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
$is_win
= DIRECTORY_SEPARATOR == ‘\’;
?>


– 不用函数
– Win98/NT/2000/XP/Vista/Longhorn/Shorthorn/Whistler…通用
– 一直可用

时间问题 (PHP>5.1.0 ONLY)

你如何在你的软件中得知现在的时间?简单,「time() time() again, you ask me…」。

不过总归会调用函数,慢。

现在好了,用 $_SERVER[‘REQUEST_TIME’],不用调用函数,又省了。

加速 PCRE

– 对于不用保存的结果,不用 (),一律用 (?

这样 PHP 不用为符合的内容分配内存,省。效率提升 15% 左右。

– 能不用正则,就不用正则,在分析的时候仔细阅读手册「字符串函数」部分。有没有你漏掉的好用的函数?

例如:

strpbrk()
strncasecmp()
strpos()/strrpos()/stripos()/strripos()

加速 strtr

如果需要转换的全是单个字符的时候,用字符串而不是数组来做 strtr:

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
$addr
= strtr($addr, "abcd", "efgh"); // good
$addr = strtr($addr, array(‘a’ => ‘e’,
                           
// …
                           
)); // bad
?>

效率提升:10 倍。

不要做无谓的替换

即使没有替换,str_replace 也会为其参数分配内存。很慢!解决办法:

– 用 strpos 先查找(非常快),看是否需要替换,如果需要,再替换

效率:

– 如果需要替换:效率几乎相等,差别在 0.1% 左右。
– 如果不需要替换:用 strpos 快 200%。

邪恶的 @ 操作符

不要滥用 @ 操作符。虽然 @ 看上去很简单,但是实际上后台有很多操作。用 @ 比起不用 @,效率差距:3 倍。

特别不要在循环中使用 @,在 5 次循环的测试中,即使是先用 error_reporting(0) 关掉错误,在循环完成后再打开,都比用 @ 快。

善用 strncmp

当需要对比「前 n 个字符」是否一样的时候,用 strncmp/strncasecmp,而不是 substr/strtolower,更不是 PCRE,更千万别提 ereg。strncmp/strncasecmp 效率最高(虽然高得不多)。

慎用 substr_compare (PHP5 ONLY)

按照上面的道理,substr_compare 应该比先 substr 再比较快咯。答案是否定的,除非:

– 无视大小写的比较
– 比较较大的字符串

不要用常量代替字符串

为什么:

– 需要查询杂凑表两次
– 需要把常量名转换为小写(进行第二次查询的时候)
– 生成 E_NOTICE 警告
– 会建立临时字符串

效率差别:700%。

不要把 count/strlen/sizeof 放到 for 循环的条件语句中

贴士:我的个人做法

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
for ($i = 0, $max = count($array);$i < $max; ++$i);
?>

效率提升相对于:

– count 50%
– strlen 75%

短的代码不一定快

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
// longest
if ($a == $b) {
    
$str .= $a;
} else {
    
$str .= $b;
}

// longer
if ($a == $b) {
    
$str .= $a;
}
$str .= $b;

// short
$str .= ($a == $b ? $a : $b);
?>

你觉得哪个快?

效率比较:

– longest: 4.27
– longer: 4.43
– short: 4.76

不可思议?再来一个:

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
// original
$d = dir(‘.’);
while ((
$entry = $d->read()) !== false) {
     if (
$entry == ‘.’ || $entry == ‘..’) {
         continue;
     }
}

// versus
glob(‘./*’);

// versus (include . and ..)
scandir(‘.’);
?>

哪个快?

效率比较:

– original: 3.37
– glob: 6.28
– scandir: 3.42
– original without OO: 3.14
– SPL (PHP5): 3.95

画外音:从此也可以看出来 PHP5 的面向对象效率提高了很多,效率已经和纯函数差得不太多了。

提高 PHP 文件访问效率

需要包含其他 PHP 文件的时候,使用完整路径,或者容易转换的相对路径。

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php

include ‘file.php’; // bad approach

incldue ‘./file.php’; // good

include ‘/path/to/file.php’; // ideal

?>

物尽其用

PHP 有很多扩展和函数可用,在实现一个功能的之前,应该看看 PHP 是否有了这个功能?是否有更简单的实现?

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
$filename
= "./somepic.gif";
$handle = fopen($filename, "rb");
$contents = fread($handle, filesize($filename));
fclose($handle);

// vs. much simpler

file_get_contents(‘./somepic.gif’);
?>

关于引用的技巧

引用可以:

– 简化对复杂结构数据的访问
– 优化内存使用

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
$a
[‘b’][‘c’] = array();

// slow 2 extra hash lookups per access
for ($i = 0; $i < 5; ++$i)
    
$a[‘b’][‘c’][$i] = $i;

// much faster reference based approach
$ref =& $a[‘b’][‘c’];
for (
$i = 0; $i < 5; ++$i)
    
$ref[$i] = $i;
?>

QUOTE:
// PHP CODE Highliting for CU by dZ902

<?php
$a
= ‘large string’;

// memory intensive approach
function a($str)
{
     return
$str.‘something’;
}

// more efficient solution
function a(&$str)
{
    
$str .= ‘something’;
}
?>

==============================================
参考资料

http://ilia.ws

Ilia 的个人网站,Blog,他参与的开发以及出版的一些稿物链接等等。

http://ez.no

eZ components 官方网站,eZ comp 是针对 PHP5 的开源通用库,以效率为己任,Ilia 也参与了开发。

http://phparch.com

php|architect,不错的 php 出版商/培训组织。买不起或者买不到的话,网上可以下到很多经典的盗版。

http://talks.php.net

PHP 会议上的演讲合集,现在还不是很丰富,不过内容都是让人一看就容易废寝忘食的好东东,推荐早上睡眼朦胧的时候或者吃完午饭仔细研究,否则你会忘记吃饭和睡觉的!

Read: 930

关于css class与id的命名 比较通用的名字

转自:http://jakewljoxygen.spaces.live.com/blog/cns!9b827d074e559d7f!438.entry

常用的CSS命名规则:
头:header
内容:content/container
尾:footer
导航:nav
侧栏:sidebar
栏目:column
页面外围控制整体布局宽度:wrapper
左右中:left right center
登录条:loginbar
标志:logo
广告:banner
页面主体:main
热点:hot
新闻:news
下载:download
子导航:subnav
菜单:menu
子菜单:submenu
搜索:search
友情链接:friendlink
页脚:footer
版权:copyright
滚动:scroll
内容:content
标签页:tab
文章列表:list
提示信息:msg
小技巧:tips
栏目标题:title
加入:joinus
指南:guild
服务:service
注册:regsiter
状态:status
投票:vote
合作伙伴:partner

(二)注释的写法:
/* Footer */
内容区
/* End Footer */

(三)id的命名:

(1)页面结构
容器: container
页头:header
内容:content/container
页面主体:main
页尾:footer
导航:nav
侧栏:sidebar
栏目:column
页面外围控制整体布局宽度:wrapper
左右中:left right center

(2)导航
导航:nav
主导航:mainbav
子导航:subnav
顶导航:topnav
边导航:sidebar
左导航:leftsidebar
右导航:rightsidebar

菜单:menu
子菜单:submenu
标题: title
摘要: summary

(3)功能
标志:logo
广告:banner
登陆:login
登录条:loginbar
注册:regsiter
搜索:search
功能区:shop

标题:title
加入:joinus
状态:status
按钮:btn
滚动:scroll

标签页:tab
文章列表:list
提示信息:msg
当前的: current
小技巧:tips
图标: icon
注释:note

指南:guild
服务:service
热点:hot
新闻:news
下载:download
投票:vote
合作伙伴:partner
友情链接:link
版权:copyright

(四)class的命名:

(1)颜色:使用颜色的名称或者16进制代码,如
.red { color: red; }
.f60 { color: #f60; }
.ff8600 { color: #ff8600; }

(2)字体大小,直接使用"font+字体大小"作为名称,如
.font12px { font-size: 12px; }
.font9pt {font-size: 9pt; }

(3)对齐样式,使用对齐目标的英文名称,如
.left { float:left; }
.bottom { float:bottom; }

(4)标题栏样式,使用"类别+功能"的方式命名,如
.barnews { }
.barproduct { }
注意事项::
1.一律小写;
2.尽量用英文;
3.不加中杠和下划线;
4.尽量不缩写,除非一看就明白的单词.
主要的 master.css
模块 module.css
基本共用 base.css
布局,版面 layout.css
主题 themes.css
专栏 columns.css
文字 font.css
表单 forms.css
补丁 mend.css
打印 print.css

———————————————————-

Gik 注:

———————————————————-

今天无意中看到的, 想起大堆页面共用一个css文件时那错综复杂的名字…..
觉得,一套易于理解切相对通用的命名规则还是很有用的

这一套感觉比较全一些 就收过来了

下面是另一套 也不错

———————————————————–

转自:http://www.j2box.com/blog/post/17.html

CSS 命名规范

CSS 命名规范

XHTML-CSS写作建议

  1. 所有的xhtml代码小写
  2. 属性的值一定要用双引号("")括起来,且一定要有值
  3. 每个标签都要有开始和结束,且要有正确的层次
  4. 空元素要有结束的tag或于开始的tag后加上"/"
  5. 表现与结构完全分离,代码中不涉及任何的表现元素,如style、font、bgColor、border等
  6. <h1>到<h5>的定义,应遵循从大到小的原则,体现文档的结构,并有利于搜索引擎的查询。
  7. 给每一个表格和表单加上一个唯一的、结构标记id
  8. 给重要的区块加上注释,如:
  9. 给图片加上alt标签
  10. 所有的标签必须进行合理的嵌套
  11. 根元素前必须有元素,宣告使用那一种DTD
  12. 根元素必须有xmlns属性来指定使用http://www.w3.org/1999/xhtml的namespace

CSS样式表规范:

  1. id和class命名采用该版块的英文单词或组合命名,并第一个单词小写,第二个单词首个字母大写,如:newRelease(最新产品/new+Release)
  2. CSS样式表各区块用注释说明
  3. 尽量使用英文命名原则
  4. 不用加中杠和下划线
  5. 尽量不缩写,除非一看就明白的单词

CSS命名规范

这段时间由于工作的需要对CSS的命名做了一些研究,主要是想让作出的文档等规范,更能让人看懂和读懂。

DIV CSS名称 说明
网站公用相关
Container div #container 容器
Header or banner div #header 页头部分
Main or global navigation div #mainNav 主导航
Menu #menu 菜单
Sub Menu #submenu 子菜单
Left or right side columns #sidebarA, #sidebarB 左边栏或右边栏
Main div #main 页面主体
Content div #content 内容部分
The main content area #contentMain 主要内容区域
Footer div #footer 页脚部分
Tag #tag 标签
Message #msg #message 提示信息
Tips #tips 小技巧
Vote #vote 投票
Friend Link #friendlink 友情连接
Title #title 标题
Summary #summary 摘要
Sub-navigation list #subNav 二级导航
Search input #searchInput 搜索输入框
Search output #searchOutput 搜索输出和搜索结果相似
Search #search 搜索
Search results #searchResults 搜索结果
Copyright information #copyright 版权信息
brand #branding 商标
branding-logo #brandingLogo LOGO
Site information #siteinfo 网站信息
Copyright information etc. #siteinfoLegal 法律声明
Designer or other credits #siteinfoCredits 信誉
Join us #joinus 加入我们
Partnership opportunities #partner 合作伙伴
Services #service 服务
Regsiter #regsiter 注册
Status #status 状态
电子贸易相关
Products .products 产品
Products prices .productsPrices 产品价格
Products description .productsDescription 产品描述
Products review .productsReview 产品评论
Editor’s review .editorReview 编辑评论
New release .newsRelease 最新产品
Publisher .publisher 生产商
Screen shot .screenshot 缩略图
FAQ .faqs 常见问题
Keyword .keyword 关键词
Blog .blog 博客
Forum .forum 论坛

Read: 862

还早…再写会…..

"还早…再写会….."

最近不知道是思维迟钝了还是智力低下了……….还是怎么的……

每天都有这句话,每天都那么晚睡….每天都有写不完的程序

每天都是面对那台机器….

我在我的世界走失了….

从前 在电脑旁, 混迹与internet的我似乎从来不会孤独

但我现在越来越感觉到孤独 寂寞

特别是每当夜深人静一个人静静听着自己打字的嗒嗒的声音…..

每当这时候我总会感觉我好像离这个世界很远, 或者自己根本不属于这个世界………

额…牢骚发完了….程序还得继续写……….

项目进度还得赶啊…郁闷

Read: 757