LINUXQQ

一月 23, 2011

linux 无线网络上网

Filed under: linux — admin @ 10:33 下午

昨天学习了下终端界面下的无线网络配置,写下来和大家分享下,也供自己以后忘记了的话可以查询^_^

先介绍两个基本命令:

iwconfig    #与ifconfig类似,显示或配置无线网卡的参数

iwlist        #显示无线AP的讯息。普通帐户要使用sudo权限才能执行成功。否则提示wlan0     Interface doesn’t support scanning

配置步骤:

0.关闭NetworkManager               

·········10········20········30········40········50········60········70········80········90

1./etc/init.d/NetworkManger stop   #runlevel 3和5,都要关闭NetworkManager才能手动来配置无线网络

1.启用无线网卡

·········10········20········30········40········50········60········70········80········90

1.ifconfig wlan0 up                          #wlan0是我的无线网卡,你的可能是eth0或者eth1之类的

2.搜索SSID

·········10········20········30········40········50········60········70········80········90
1.iwlist wlan0 scanning                    #这条命令要用root权限来执行,否则提示无线网卡不支持扫描

3.设置无线参数

·········10········20········30········40········50········60········70········80········90

1.iwconfig wlan0 essid "ssid名称" key 无线网络密钥                    #16进制密钥使用这条命令
2.iwconfig wlan0 essid "ssid名称" key s:无线网络密钥                  #ASCII密钥使用这条命令、

4.从无线路由器dhcp获取IP地址,成功后,就可以上网了。

·········10········20········30········40········50········60········70········80········90
1.dhclient wlan0

 

几个要注意的地方:

1.记得一定要先关闭NetworkManager,此实验才能成功

2.无线网络密码,16进制的密码使用步骤3第一指令,ASCII使用步骤3第二条指令

3.如果要使用ifup wlan0来启用无线网卡,请先确认ifcfg-wlan0这个配置文件是否存在。如果不存在,ifup将不能执行,请改用命令ifconfig wlan0 up

linux 关闭

Filed under: linux — admin @ 10:32 下午

我推荐使用init  
  shutdown -r now 立即重启
 
  Linux命令:shutdown
 
  功能说明:系统关机指令。
 
  语  法:shutdown [-efFhknr][-t 秒数][时间][警告信息]
 
  补充说明:shutdown指令可以关闭所有程序,并依用户的需要,进行重新开机或关机的动作。
 
  参  数:
 
  -c  当执行”shutdown -h 11:50″指令时,只要按+键就可以中断关机的指令。
 
  -f  重新启动时不执行fsck(磁盘维护)。
 
  -F  重新启动时执行fsck.
 
  -h  将系统关机。
 
  -k  只是送出信息给所有用户,但不会实际关机。
 
  -n  不调用init程序进行关机,而由shutdown自己进行。
 
  -r  shutdown之後重新启动。
 
  -t<秒数>  送出警告信息和删除信息之间要延迟多少秒。
 
  [时间]  设置多久时间後执行shutdown指令。
 
  [警告信息]  要传送给所有登入用户的信息。
 
  reboot 快速重启(跳过sync过程,即同步化)
 
  启动级别(0~6),位于/etc/inittab:
 
  对各个运行级的详细解释:
 
  0 为停机,机器关闭。(千万不要设置到此级别)
 
  1 为单用户模式,就像Win9x下的安全模式类似。
 
  2 为多用户模式,但是没有NFS支持。
 
  3 为完整的多用户模式,是标准的运行级。
 
  4 一般不用,在一些特殊情况下可以用它来做一些事情。例如在笔记本电脑的电池用尽时,可以切换到这个模式来做一些设置。
 
  5 就是X11,进到X Window系统了。
 
  6 为重启,运行init 6机器就会重启。(千万不要设置到此级别)
 
  shutdown、Halt、init、reboot的区别:
 
  shutdown调用时,会发送信号(signal)给init程序,要求它改变runlevel,具体会根据参数决定(关闭或重起)。
 
  halt和reboot都是shutdown的某个命令的链接,halt相当于shutdown -h now,也就是关闭;reboot相当于shutdown -r now,作用是重启系统。
 
  Init作为Linux系统的首发程序,有多个运行级(runlevel),比如0-关闭 1-单用户模式 3-字符界面 5-图形界面 6-重启,因此使用Init来进行关机或重启操作和shutdown差不多,且比shutdown更直接(不需要发送信号了的说)。

一月 22, 2011

python 守护进程

Filed under: python — admin @ 6:18 下午

xmuruijie默认是以守护进程的方式启动的,xmuruijie.py中实现了一个名为daemonize的全局函数,该函数负责建立守护进程。xmuruijie启动代码如下:

view source
 

print?

01 if 'start' == action:
02   
03     #如果pid已经存在,那么退出程序
04     if pid:
05         mess = "Start aborded since pid file '%s' exists.\n"
06         sys.stderr.write(mess % pidfile)
07         sys.exit(1)
08   
09     #都是以daemon的方式运行的?
10     daemonize( stdout,stderr,stdin,pidfile )
11     return

daemonize函数包含了经典的守护进程创建代码,只不过以前看到的是用C实现,这里改成了Python。这段代码依次做了以下事情:
1、创建子进程,父进程退出。
2、将工作目录切换到根目录。
3、将掩码设置为0。
4、创建新的会话,子进程成为该会话中唯一的进程组的领头进程。
5、再创建子进程,父进程退出。
6、重定向标准输入、标准输出、标准错误到日志文件中。

所有源代码如下:

view source
 

print?

01 def daemonize(stdout='/dev/null', stderr=None, stdin='/dev/null',
02         pidfile=None ):
03     '''
04     This forks the current process into a daemon.
05     The stdin, stdout, and stderr arguments are file names that
06     will be opened and be used to replace the standard file descriptors
07     in sys.stdin, sys.stdout, and sys.stderr.
08     These arguments are optional and default to /dev/null.
09     Note that stderr is opened unbuffered, so
10     if it shares a file with stdout then interleaved output
11     may not appear in the order that you expect.
12     '''
13     # Do first fork.
14     try:
15         pid = os.fork()
16         if pid > 0: sys.exit(0) # Exit first parent.
17     except OSError, e:
18         sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
19         sys.exit(1)
20   
21     # Decouple from parent environment.
22     os.chdir("/")
23     os.umask(0)
24     os.setsid() 
25   
26     # Do second fork.
27     try:
28         pid = os.fork()
29         if pid > 0: sys.exit(0) # Exit second parent.
30     except OSError, e:
31         print 'second fork error'
32         sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
33         sys.exit(1)
34   
35     # Open file descriptors and print start message
36     if not stderr: stderr = stdout
37     si = file(stdin, 'r')
38     so = file(stdout, 'w+')
39     se = file(stderr, 'a+', 0)
40     pid = str(os.getpid())
41     print "Start with Pid: %s\n"  % pid
42     sys.stderr.flush()
43     if pidfile: file(pidfile,'w+').write("%s\n" % pid)
44   
45     # Redirect standard file descriptors.
46     sys.stdout.flush()
47     sys.stderr.flush()
48     os.dup2(si.fileno(), sys.stdin.fileno())
49     os.dup2(so.fileno(), sys.stdout.fileno())
50     os.dup2(se.fileno(), sys.stderr.fileno())

 

第一章, 原理

本章仅作了解就可以了, 因为这些细节性的东西实在是无聊,
所以我强烈推荐你直接跳到第二章。

   当然, 如果你有足够的耐心和能力, 还是看下去吧 ……

通常我们把后台进程叫做 "守护进程"、"精灵进程", 或者 daemon。
在 Unix 下, 我们使用 fork 实现。

   import os
   def daemonize():
      # 首先 fork 出两个进程
      pid = os.fork()

      # pid 非零的是父进程,
      # 父进程就是你用命令启动的那个程序。
      #
      if pid != 0:
         # 接着我们退出父进程
         # 这样你的命令行程序就退出了。
         #
         # 父进程退出后, 子进程就被系统托管了
         # 这时子进程就转入后台执行
         os._exit(0)

      # 子进程开始
      # 我们在这里启动后台程序 (服务器)
      os.system('python server.py')
      # 当然, 你永远不会使用 os.system 来启动一个程序
      # os.system 会启动 python、server.py 还有你不希望看到的 sh 进程

当然, 真正能用的 daemonize 程序还要作更多的事情,
这些都被记载在典籍《Unix 高级环境编程》中。

我归纳了一下, 分别是一下几个方面。

   1. 切换程序的身份。
      请看 Apache 的设计, 在使用 root 得到 80 端口后旋即转换成 nobody (www-data) 用户。
      很明显, 使用 root 身份执行一个程序是危险的, 后台程序的身份不应该是 root。

         最实用的选择是: 当配置文件里没有说明以何身份执行时,
         就以当前用户的身份启动后台进程。

   2. 自定义部分信号处理程序。

         如果不是必须, 依我看还是不要做太多信号处理,
         否则你的服务器很可能将只能吃到 kill -9 才可退出了, 这显然很蠢。
      如果你不想看到太多的 undead, 处理 SIGCHLD 是必须的。

   3. 重定向 stdin、stdout 和 stderr。
      标准输入输出对 daemon 进程而言没有意义, 因为后台进程是没有终端可供使用的。

         注意, 这里是重定向而不是关闭, 这样可以避免程序在 print 的时候出错。

         我们通常会将 stdout、stderr 重定向到日志文件。
         /dev/nul 是选择之一。
         stdin 是没有意义的。

   4. setsid(), umask(), chdir() 逐一 google。这里不赘述了。

   5. 把 pid 写到 xxx.pid 文件中去。
      当我们需要结束后台进程的时候, 我们就可以从 pid 文件中得到子进程的 pid,
      然后 kill PID。

目前, Python 最好的 Daemon 库依然是 Zope 的 zdaemon,
欲了解健壮的 Daemon 实现, 可以阅读 zdaemon 的源代码。
当然, 阅读 zdaemon 源码是比较痛苦的, 我自己也比较痛恨 zdaemon 的编码风格。

   我痛恨一切没有必要的, 过度的 OO 设计。

zdaemon 的贡献是它引入了 "进程控制器" 这个概念, 它的 daemonize 使用了两次 fork。

   # zdaemon.py
   import os
   def zdaemonize():
      # 首次 fork, 进入后台
      pid = os.fork()

      if pid != 0:
         os._exit(0)

      # 第二次 fork
      pid = os.fork()

      # 父进程, Daemon 管理器
      if pid != 0:
         # 启动进程管理器服务器
         # 这里, manager_server 是假想的
         import manager_server
         manger_server.serve_forever()

      # 子进程, 启动后台服务
      os.system('python server.py')

进程管理器 manger_server 通常是一个 TCP 服务, 他使用 Unix Socket 与外界交互。
这样, pid 文件就变成了 Unix Socket 文件。
你通过 Unix Socket (TCP Socket) 接口对进程管理器发送控制指令,
比如 'start'、'status' 和 'stop',
进程管理器再对他的子进程 (后台守护进程) 发送控制信号, 启动或者关闭守护进程。

通过进程管理器, 后台进程的控制就和后台进程的运行逻辑分开了。

zdaemon 也有一个致命缺点, 其过度对象化的设计, 使封装层次失控,
加上采用了底层的 Unix Socket, 使其代码量过度膨胀。

   人类能够理解的代码行数是有限制的。
      --《Unix 编程艺术》

   所以 Python 的语法决定了 Python 能够编写出目前最复杂的程序。
   代码量失控是 Python 的最大敌人, 这说明我们可能正在用 Java 写 Python。

为此我修改了 zdaemon, 将它实现在 270 行代码中。
用 Local XMLRPC Server (Unix Socket) 取代 zdaemon 的 Socket 底层,
为我赢得了不少行数。

同样, 在编写 Local XMLRPC Server 的时候, 再次遇到 Python 标准库 SimpleXMLRPCServer.py
的过度封装问题, 有兴趣的话大家可以阅读第三章 Local XMLRPC Server 的实现部分,

   过度向对象实际上就是完全无法重用, 这是一个典型的例子。

使用 XMLRPC Server 的额外好处,
就是让我们可以更方便地增加除了 start、stop、status 这种控制命令。

   daemon = Daemon(...)
   daemon.register_function(...)

   不过, 额外的控制命令, 通常是不需要的。

我的 daemon 程序 (daemon.py) 源码放在第三章中,
同样, 阅读源码是一件枯燥的事情, 你可以忽略掉第三章。
但是第二章是必须理解的。

第二章、使用 daemon.py 的通用范例
   你可以不用修改就用于你的项目

#!/usr/bin/env python2.5
# -*- coding: utf-8 -*-

import os, sys
from os import fork
from time import sleep
from sys import stderr, stdout
from socket import error as SocketError
from traceback import print_exc

import schema # 载入配置信息, 还记得《配置文件》一招鲜吗?
import pyetc  # ... 要不要复习一下 :) 

from daemon import Daemon, ServerProxy, Fault, \
   error as DaemonError

## #

def usage():
   print '使用方法: %s start|stop|status' %sys.argv[0]

def start():
   # 读取配置文件
   # demo.conf
   pyetc.load(schema.ETC('demo.conf'), env=schema.env)
   conf = schema.config.daemon
   # ... 请见《配置文件一招鲜》最后一个范例

   try:
      # 创建 Daemon 对象
      daemon = Daemon(
         address = conf.address, # 进程控制器地址/pid 文件位置
         program = conf.program, # 后台进程程序位置
         verbose = conf.verbose  # 调试
         )

      print '进程管理器已经启动'

      # 启动后台进程
      #    daemon(arg1, arg2, ...)
      #    参数 arg1, arg2 ... 将被用于启动后台进程,
      #    这里相当于命令行:
      #       program.py arg1 arg2 ...
      daemon()

   except DaemonError, msg:
      print '进程管理器未启动, 原因是: ', msg

   except:
      print_exc(file=stderr)

def stop():
   pyetc.load(schema.ETC('demo.conf'), env=schema.env)
   conf = schema.config.daemon

   # 取得进程控制器
   try:
      daemon = ServerProxy(conf.address)
      daemon.stop()

      print '进程已经退出'

   except SocketError:
      print '进程管理器未启动'

   except Fault:
      print '进程管理器已被强制关闭'

   except:
      print_exc(file=stderr)

def status():
   pyetc.load(schema.ETC('demo.conf'), env=schema.env)
   conf = schema.config.daemon

   try:
      daemon = ServerProxy(conf.address)
      status = daemon.status()

      if status == 'running':
         print '进程 "%s" 正在运行' %conf.program

      elif status == 'stopped':
         stdout.write( ('进程管理器正在运行, 但是进程 "%s" 已经停止, '
            '正在停止进程管理器 ... '
            ) %conf.program )

         stop()

      else:
         print '进程管理器正在运行, 进程状态未知'

   except SocketError:
      print '进程管理器未启动'

   except:
      print_exc(file=stderr)

## #

# 解析参数

if len(sys.argv) != 2:
   usage()

elif sys.argv[1] == 'start':
   start()

elif sys.argv[1] == 'stop':
   stop()

elif sys.argv[1] == 'status':
   status()

else: usage()

第三章、附件: daemon.py

import os, sys
from httplib import HTTP, HTTPConnection
from pwd import getpwnam, getpwuid
from signal import signal as setsignal, SIGCHLD, SIGTERM
from sys import stderr, stdout
from urllib import urlopen
from SocketServer import UnixStreamServer
from socket import socket, error as SocketError, \
   AF_UNIX, SOCK_STREAM
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher, \
   SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
from xmlrpclib import Fault, Transport, dumps as xmlrpc_dumps, \
   _Method as _XMLRPCMethod, ServerProxy as ServerProxy_N___G
from os import execv, chdir, chmod, fork, geteuid, getpid, \
   kill, setgid, setuid, umask, unlink, waitpid, \
   error as OSError, WNOHANG

class error(Exception): pass

class nul:
   write = staticmethod(lambda s: None)
   flush = staticmethod(lambda  : None)
   read  = staticmethod(lambda n: ''  )

class UnixStreamXMLRPCServer(UnixStreamServer, SimpleXMLRPCDispatcher):
   def __init__(self, address, requestHandler=SimpleXMLRPCRequestHandler,
      allow_none=False, encoding=None):

      self.logRequests = False

      SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
      UnixStreamServer.__init__(self, address, requestHandler)

class Daemon:
   def __init__(self, **args):
      address      =           args[ 'address'             ]
      allow_none   =       args.get( 'allow_none', True    )
      encoding     =       args.get( 'encoding'  , 'utf-8' )

      self.verbose =       args.get( 'verbose'   , False   )
      self.stdout  =       args.get( 'stdout'    , nul     )
      self.stderr  =       args.get( 'stderr'    , nul     )

      try:
         ServerProxy(address).ping()
      except SocketError:
         pass
      else:
         raise error, 'Another daemon is already up using socket %s' %repr(address)

      if isinstance(address, str):
         try:
            unlink(address)
         except OSError:
            pass

         self.manager = UnixStreamXMLRPCServer(address,
            allow_none=allow_none, encoding=encoding)

         self.pidfile = address
      else:
         self.manager = SimpleXMLRPCServer(address,
            allow_none=allow_none, encoding=encoding)

      self.pid     = None
      self.running = True

      self.program       =     args[ 'program'             ]

      DaemonizeTools.setuid(
         user       = args.get( 'user'      , None    )  )

      SignalTools.setsignals(self)

      DaemonizeTools.daemonize(
         directory  = args.get( 'directory' , None    ),
         umask      = args.get( 'umask'     , 022     )  )

      self.register_function = lambda *args: (
         self.manager.register_function(*args) )

      self.register_function(lambda: self.stop()  , 'stop'  )
      self.register_function(lambda: self.status(), 'status')
      self.register_function(lambda: True         , 'ping'  )

   def __call__(self, *args):
      if not self.verbose:
         DaemonizeTools.close_files(self.stdout, self.stderr)
         del self.stdout, self.stderr

      pid = fork()

      if pid != 0:
         self.pid = pid
         while self.running:
            self.manager.handle_request()

         return pid

      else:
         try:
            for i in xrange(3, 100):
               try:
                  os.close(i)
               except OSError:
                  pass

            try:
               execv(sys.executable, tuple(
                  [sys.executable, self.program] + list(args) ) )
            except OSError, err:
               print >> stderr, ( 'can\'t exec %r: %s\n'
                  % (self.program, err) )

         finally:
            os._exit(127)

   def status(self):
      if not self.pid:
         return 'stopped'
      else:
         return 'running'

   def stop(self):
      if not self.pid:
         self.running = False
         if hasattr(self, 'pidfile'):
            try:
               unlink(self.pidfile)
            except OSError:
               pass

         raise error, 'no subprocess running'

      kill(self.pid, SIGTERM)
      self.running = False
      if hasattr(self, 'pidfile'):
         try:
            unlink(self.pidfile)
         except OSError:
            pass

class UnixStreamHTTPConnection(HTTPConnection):
   def connect(self):
      self.sock = socket(AF_UNIX, SOCK_STREAM)
      self.sock.connect(self.host)

class UnixStreamHTTP(HTTP):
   _connection_class = UnixStreamHTTPConnection

class UnixStreamTransport(Transport):
   def make_connection(self, host):
      return UnixStreamHTTP(host)

class UnixStreamServerProxy_NG:
   def __init__(self, uri, transport=None, encoding=None, verbose=0,
      allow_none=0, use_datetime=0):

      self.__host = uri
      self.__handler = '/RPC2'

      if not transport:
         self.__transport = UnixStreamTransport(use_datetime=use_datetime)

      self.__encoding = encoding
      self.__verbose = verbose
      self.__allow_none = allow_none

   def __request(self, methodname, params):
      request = xmlrpc_dumps(params, methodname, encoding=self.__encoding,
         allow_none=self.__allow_none)

      response = self.__transport.request(
         self.__host, self.__handler, request,
         verbose=self.__verbose )

      if len(response) == 1:
         response = response[0]

      return response

   def __getattr__(self, name):
      return _XMLRPCMethod(self.__request, name)

def ServerProxy(address, **args):
   if isinstance(address, str):
      return UnixStreamServerProxy_NG(address, **args)

   else:
      host, port = address
      host = (host, '127.0.0.1')[host == '0.0.0.0']
      return ServerProxy_N___G('http://%s:%d' %(host, port), **args)

class DaemonizeTools:
   @staticmethod
   def setuid(**args):
      user = args['user']
      if user is None:
         return

      try:
         uid = int(user)

      except ValueError:
         try:
            pwrec = pwd.getpwnam(user)
         except KeyError:
            raise error, 'username %r not found' % user

         uid = pwrec[2]

      else:
         try:
            pwrec = pwd.getpwuid(uid)
         except KeyError:
            raise error, 'uid %r not found' % user

      euid = geteuid()
      if euid != 0 and euid != uid:
         raise error, 'only root can change users'

      setgid(pwrec[3])
      setuid(uid)

   @staticmethod
   def daemonize(**args):
      pid = fork()
      if pid != 0:
         os._exit(0)

      if args['directory']:
         try:
            chdir(args['directory'])
         except OSError, err:
            print >> stderr, ( 'can\'t chdir into %r: %s'
               % (args['directory'], err) )
         else:
            print >> stderr, ( 'set current directory: %r'
               % args['directory'] )

      os.setsid()
      umask(args['umask'])

   @staticmethod
   def close_files(stdout, stderr):
      os.close(0)
      sys.stdin = sys.__stdin__ = nul
      os.close(1)
      sys.stdout = sys.__stdout__ = stdout
      os.close(2)
      sys.stderr = sys.__stderr__ = stderr

class SignalTools:
   daemon = None

   @staticmethod
   def setsignals(daemon):
      SignalTools.daemon = daemon
      setsignal(SIGCHLD, SignalTools.sigchild)

   @staticmethod
   def sigchild(sig, frame):
      try:
         pid, sts = waitpid(-1, WNOHANG)
         if pid == SignalTools.daemon.pid:
            SignalTools.daemon.pid = None

      except OSError:
         return

一月 21, 2011

linux kudzu

Filed under: linux — admin @ 6:33 下午

自动配置安装 如果安装完Linux系统后,又添加了新的硬件,那么系统必须载入正确的驱动程序才可以使用它。

Kudzu服务默认每次启动时都要运行,如果需要缩短启动时间,使用下面命令可以停止系统启动时的kudzu服务: # chkconfig kudzu off 如果要安装新的硬件,可以手动运行kudzu程序。

以上介绍了Linux下驱动程序的大体结构、主要的加载方式和相关配置文件,在安装Linux时加载驱动程序,并且根据需要定制自己的引导盘,在安装完成后安装新的、即插即用硬件。

Redhat Linux用kudzu查看已经安装的设备
我们通常都把kudzu当AIX的cfgmgr和Solaris 的devfsadm用

当然它还可以用来查看系统中已有的设备。

kudzu – detects and configures new and/or changed hardware on a system

       -p, –probe
              Print probe information to the screen, and do not actually configure or unconfigure any devices.

[root@node2 ~]# kudzu -p|more
-
class: OTHER
bus: PCI
detached: 0
driver: unknown
desc: “Intel Corporation 82371AB/EB/MB PIIX4 ACPI”
vendorId: 8086
deviceId: 7113
subVendorId: 15ad
subDeviceId: 1976
pciType: 1
pcidom:    0
pcibus: 0
pcidev: 7
pcifn: 3
-
class: OTHER
bus: PCI
detached: 0
driver: unknown
desc: “Intel Corporation 82371AB/EB/MB PIIX4 ISA”

具体还有各种比方只probe bus等等一些参数请查看man手册

也可以从文件中查:
/etc/sysconfig/hwconf
   Listing of current installed hardware.

一月 20, 2011

iis+php

Filed under: linux — admin @ 6:14 下午

一:让 IIS6.0 支持 PHP -=> php4.3.9 的安装配置

不建议使用安装版 这里选用了 php4.3.9 的解压版

第一步 解开php-4.3.9-Win32.zip压缩包 你可以把它放在C:\PHP下面

第二步 把 C:\PHP下面的 php.ini-dist 文件复制到C:\WINDOWS目录下 并改名成php.ini 根据不同情况你可以自行修改某些参数 首先 我们需要告知PHP在何处可以找到其扩展功能模块文件 下面修改 C:\windows\php.ini 文件 需要注意的如下

查找 extension_dir 字串 修改为你 PHP 目录里 extensions 的路径:

; Directory in which the loadable extensions (modules) reside
extension_dir = “C:\php\extensions”
如上 设为PHP文件的所在目录即可 本例中可以设为“extension_dir= “C:\php\extensions””
如果用5.0 目录将是“extension_dir= “C:\php\ext””
第三步 把 C:\php\php4ts.dll 复制到 C:\windows(winnt)\system32目录下

第四步 控制面版——》管理工具——》Internet服务管理器——》点选“Web 服务扩展”——》在右边窗口点击“添加一个新的 Web 服务扩展”——》扩展名为 “PHP”——》再点击“添加”——》在出现的窗口里填上“C:\PHP\sapi\php4isapi.dll” 并确定 然后再点选 Web 服务扩展 PHP 并选择允许 如图所示

第五步 在“默认网站属性”窗口上按 “主目录”标签 点“配置”按钮 在弹出的“映谢”窗口中点取“添加”按钮,在弹出的“添加/编辑应用程序扩展名映像”对话框中的“可执行文件”文本框中输入“c:\PHP\sapi\php4isapi.dll” “扩展名”文本框中输入“.php”(注意一定要有那个点) 并勾选 “检查文件是否存在”项 确定 如图所示

第六步 在“默认Web站点属性”窗口上点取“ISAPI筛选器”标签,点击“添加”按钮,在弹出的“筛选器属性”窗口的“筛选器名称”中输入“PHP” “可执行文件”中浏览选定“c:\PHP\sapi\php4isapi.dll” 然后确定 如图所示

A:先停止 IIS 6.0的运行 再重新启动IIS 6.0 意在开始对 PHP 加载 见图

B:在“默认Web站点属性”窗口上点取“ISAPI筛选器”标签 如果看到 PHP 的箭头绿色且向上 证明 PHP 已经被 IIS 6.0 顺利加载起来了 见图

第七步 在“默认网站属性”窗口上按 “主目录”标签 修改 如果在IIS6.0里对PHP配置为CGI运行模式 即全部加载PHP.exe 执行权限 为“脚本和可执行文件” 反之 运行在ISAPI模式下 即全部加载PHP4isapi.dll 则保持默认的”纯脚本”即可 这样可进一步加强系统的安全性 应用程序池 为 “ DefaultAppPool” 确定即可 如图所示

到了这一步 对配置PHP环境就算完成了

配置完成后 如果想测试 PHP 是否已经安装成功 可以在空间里根目录下建立一个文件 如 test.php 然后写入下面的语句

<?
phpinfo();
?>

保存后 用IE访问这个文件

http://地址/test.php

如果能见到这熟悉的页面 对配置PHP环境就真正成功了

当然 你也可以配置成 PHP运行在CGI模式

具体方法就是把原来设置的路径“ c:\PHP\sapi\php4isapi.dll ” 改为 “ c:\php\php.exe “%s” %s ” 然后把 “ 检查文件是否存在 ” 取消 然后确定 基本设置完成

最后测试……

<?
phpinfo();
?>

如果出现 CGI Error

The specified CGI application misbehaved by not returning a complete set of HTTP headers…

这是代表php是以CGI模试运行的 在php.ini找到 gi.force_redirect 把前面的分号去掉 把值改成0就行了

再次运行 成功了吧 这是PHP另一种运行模式的配置方法

下一步来配置eaccelerator

让论坛速度更快 PHP加速设置 PHP加速:eaccelerator(用Turck MMcache会出现一些莫名其妙的错误,所以大家还是用eaccelerator吧)

下载下面附件中的eaccelerator_win_4[1].3.9.rar
解压缩,把他放到C:\php\extensions\里
然后打开c:\windows\php.ini
搜索;extension=php_zip.dll
在下面添加
[eaccelerator]
zend_extension_ts=”C:\php\extensions\eaccelerator.dll”
eaccelerator.shm_size=”64″
eaccelerator.cache_dir=”F:\tem\”

注意上面的F:\tem\是用来放缓存的地方~不推荐大家把tem放在系统盘,这个大家可以自己定义.

下一步来配置zend,下载地址看本帖附件

Zend Optimizer用优化代码的方法来提高PHP 4.0应用程序的执行速度。实现的原理是对那些在被最终执行之前由运行编译器(Run-Time Compiler)产生的代码进行优化。一般情况下,执行使用Zend Optimizer的PHP程序比不使用的要快40%到100%。这意味着网站的访问者可以更快的浏览网页,从而完成更多的事务,创造更好的客户满意度。更快的反应同时也意味着可以节省硬件投资,并增强网站所提供的服务。所以,使用Zend Optimizer,就等于提高了电子商务的盈利能力。Zend Optimizer能给PHP用户带来很多益处,特别是那些运营网站的人。快速运行PHP程序可以显著降低服务器的CPU负载,并可以减少一半的反应时间,也就是从访问者点击链接到服务器开始读取页面之间的时间。

安装Zend Optimizer优化PHP程序

Zend Optimizer是由PHP核心引擎“Zend” http://www.zend.com 创建者Zend技术公司所开的免费PHP优化软件。据Zend公司透露使用这个软件某些情况下至少可以提高性能30%以上!现在我们来看看如何配置这套软件。

Zend Optimizer的安装很简单

1、运行安装文件,首先提示你选择安装目录,选择一个你喜欢的目录,单击“Next”。
2、安装向导会要求你选择当前使用的WEB服务器(Apache、IIS或其它),选择好服务器后单击“Next”
3、安装向导提示您确认php.ini的位置(默认是C:\WINDOWS\)单击“Next”,提示“备份php.ini到C:\WINDOWS\php.ini-Optimizer-bak,当卸载该软件时可以恢复到原始的php.ini)单击“Next”。
4、安装向导提示“为了继续安装程序需要重新启动IIS服务)单击“是”,安装程序开始重新启动IIS服务,然后安装程序会提示“IIS服务顺利重新启动了”单击“确定”,再单击“finish”完成安装。
5、安装完毕后程序会自动根据你的选择来修改php.ini帮助你启动这个引擎。下面我们来介绍Zend Optimizer的配置选项,帮助你最大化自定义合理的配置。

[Zend]
zend_optimizer.optimization_level=15
zend_extension_ts=”C:\Program Files\Zend\lib\ZendExtensionManager.dll”
zend_extension_manager.optimizer_ts=”C:\Program Files\Zend\lib\Optimizer-2.5.5″

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

[Zend]
zend_optimizer.optimization_level=1023
zend_optimizer.encoder_loader=0
zend_extension_ts=”C:\Program Files\Zend\lib\ZendOptimizer.dll”

(网上资料中所看到的内容,也许是版本不同造成的内容有差异)

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

现在我们来介绍上边这些配置文件中相关内容的含义:
zend_optimizer.optimization_level 《== 优化程度,这里定义启动多少个优化过程。
zend_optimizer.encoder_loader 《== 是否允许处理由Zend Encoder加密的PHP文件。
zend_extension_ts 《== 优化器所在目录。
zend_extension_manager.optimizer_ts 《== 优化器管理所在目录。

优化过程 zend_optimizer.optimization_level 详细解释

这里最为重点的部分,仔细看!Zend Opt总共有10个优化过程,从理论上说开的越多性能越好。当然,理论和实际永远都存在着差距。优化过程开启的越多对性能消耗也相对也越大,Zend Opt的10个优化过程并不相同也就是说效果不是平均的。Zend公司定义的最高值(High模式)为15,这里15指的是开启1-4号优化过程。当然,很多朋友并不满足于此,毕竟最高也只开启4个优化过程连总数的一半都没有。各个优化过程的对应的数字代码(值)如下:

不使用 0 <= 如果这样不如不装,还能节约点内存说!
优化过程1(PASS1) 1
优化过程2(PASS2) 2
优化过程3(PASS3) 4
优化过程4(PASS4) 8
优化过程5(PASS5) 16
优化过程6(PASS6) 32
优化过程7(PASS7) 64
优化过程8(PASS8) 128
优化过程9(PASS9) 256
优化过程10(PASS10) 512

以何种方式开启优化过程是通过这些数字代码(值)相加所得的和作为此参数的参数值来控制的。如我的配置文件中zend_optimizer.optimization_level = 1023 , 这里的1023是优化过程1到优化过程10全部数字代码(值)相加得到的和,表示开启全部10个优化过程。刚才所提到的Zend公司定义的High模式值为15,15表示同时开启优化过程1-4。

加密代码支持 zend_optimizer.encoder_loader 详细解释

对于这个参数,我想如果没有看过Zend Opt FAQ文档的朋友大多数并不知道。这个参数用来告诉Zend Opt是否去支持被Zend Encoder加密过的代码。默认情况下Zend Opt将支持加密过的代码。如果不使用被加密过的代码我推荐你关闭此选项。这个功能牵扯到解包反码的过程,会导致系统负荷的加重。我的朋友已经开发完毕相应的反编译工具,预计春节之后推出。

这个参数的值只有两个 0 关闭, 1 开启。默认为1,推荐设置为0。

模块定位 zend_extension_ts 、zend_extension_manager.optimizer_ts无需解释,这些参数就是Zend Optimizer相关模块在硬盘上的安装路径。

6、如何获知Zend Optimizer是否在运行?
答案很简单,只要用PHP的函数phpinfo()来检测便知,如下所示:

<?
phpinfo();
?>

显示的结果中关于Zend Optimizer的部分就象下面这样:

This program makes use of the Zend Scripting Language Engine:
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies with Zend Extension Manager v1.0.3, Copyright (c) 2003-2004, by Zend Technologies with Zend Optimizer v2.5.3, Copyright (c) 1998-2004, by Zend Technologies

表示 Zend Optimizer for PHP优化成功了。

下一步来安装mysql
解压MYSQL4.024的压缩文件包 mysql-4.0.24-win.zip 然后运行安装程序 一直按下一步就OK 可以安装到C盘 省去一些设置上的麻烦 。跟着找到 C盘下的 MYSQL 文件夹 运行bin\winmysqladmin.exe 启动MYSQL 第一次会弹出一个需要输入帐号和密码的界面 名字和密码随你欢喜填上去(这个是本地安全码 会保存在操作系统中 My.ini 文件里 只允许在本机登陆 MYSQL 以提高安全性) 确定就结束了 算是完成 MYSQL的安装了。

PS:对于论坛的安装 —— 关键到和MYSQL数据库的连接成败 所以要注意 MYSQL的超级管理员密码是空的 帐号名字为 root 并不是填刚才安装后第一次运行MYSQL时自己设置的帐号和密码(这个只是类似于OICQ的本地安全码) 否则连接失败。

【设置 MYSQL 随系统运行自动加载】

开始–>运行–> 分别逐条输入下面的命令并确定

net start mysql

services.msc

net stop iisadmin

net start w3svc

c:\mysql\bin\mysqld-nt –install

如果是出现下面的提示 那是典型的数据库未启动故障 可在 mysql\bin执行winmysqladmin.exe 启动MYSQL就运行正常了

Connect(0) to MySQL (localhost,root) failed

The URL Is:
http://www.motianlong.com/bbs/index.php?

MySQL Server Error:
Can’t connect to MySQL server on ‘localhost’ (10061) ( 2003 )

You Can Get Help In:
http://www.phpwind.net

Quote:
附: 高级配置 MySQL 数据库

为了数据的安全 一些默认值你必须进行修改 比如密码之类

(一) 连接MYSQL:

格式: mysql -h主机地址 -u用户名 -p用户密码

1、例1:连接到本机上的MYSQL

首先在打开DOS窗口,然后进入目录 C:\mysql\bin,再键入命令mysql -uroot -p,回车后提示你输密码,如果刚安装好MYSQL,超级用户root是没有密码的,故直接回车即可进入到MYSQL中了,MYSQL的提示符是:mysql>

2、例2:连接到远程主机上的MYSQL

假设远程主机的IP为:110.110.110.110,用户名为root,密码为abcd123。则键入以下命令:

mysql -h110.110.110.110 -uroot -pabcd123

(注:u与root可以不用加空格,其它也一样)

3、退出MYSQL命令

exit (回车)

(二) 修改密码:

格式:mysqladmin -u用户名 -p旧密码 password 新密码

1、例1:给root加个密码ab12。首先在DOS下进入目录C:\mysql\bin,然后键入以下命令:
mysqladmin -uroot -password ab12

注:因为开始时root没有密码,所以-p旧密码一项就可以省略了。

2、例2:再将root的密码改为djg345

mysqladmin -uroot -pab12 password djg345

(三) 增加新用户:(注意:和上面不同,下面的因为是MYSQL环境中的命令,所以后面都带一个分号作为命令结束符)

格式:grant select on 数据库.* to 用户名@登录主机 identified by “密码”

例1、增加一个用户test1密码为abc,让他可以在任何主机上登录,并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL,然后键入以下命令:
grant select,insert,update,delete on *.* to test1@”%” Identified by “abc”;
但例1增加的用户是十分危险的,你想如某个人知道test1的密码,那么他就可以在internet上的任何一台电脑上登录你的mysql数据库并对你的数据可以为所欲为了,解决办法见例2。

例2、增加一个用户test2密码为abc,让他只可以在localhost上登录,并可以对数据库mydb进行查询、插入、修改、删除的操作(localhost指本地主机,即MYSQL数据库所在的那台主机),这样用户即使用知道test2的密码,他也无法从internet上直接访问数据库,只能通过MYSQL主机上的web页来访问了。
grant select,insert,update,delete on mydb.* to test2@localhost identified by “abc”;

如果你不想test2有密码,可以再打一个命令将密码消掉。
grant select,insert,update,delete on mydb.* to test2@localhost identified by “”;

(四) 显示命令

1、显示数据库列表:
show databases;
刚开始时才两个数据库:mysql和test。mysql库很重要它里面有MYSQL的系统信息,我们改密码和新增用户,实际上就是用这个库进行操作。
2、显示库中的数据表:
use mysql; //打开库,学过FOXBASE的一定不会陌生吧
show tables;
3、显示数据表的结构:
describe 表名;
4、建库:
create database 库名;
5、建表:
use 库名;
create table 表名 (字段设定列表);
6、删库和删表:
drop database 库名;
drop table 表名;
7、将表中记录清空:
delete from 表名;
8、显示表中的记录:
select * from 表名;

=================================
=================================
mysql安装好需要优化配置一下,打开c:\windows\my.ini文件
仔细对比下面我优化过的my.ini看看哪里没有的就加进去

Copy code
#This File was made using the WinMySQLAdmin 1.4 Tool
#2005-12-4 15:37:01

#Uncomment or Add only the keys that you know how works.
#Read the MySQL Manual for instructions

[mysqld]
basedir=C:/mysql
#bind-address=192.168.1.1
datadir=C:/mysql/data
#language=C:/mysql/share/your language directory
#slow query log#=
#tmpdir#=
#port=3306
set-variable = max_connections=2500
skip-locking
#skip-networking
set-variable = key_buffer=384M
set-variable = max_allowed_packet=1M
set-variable = table_cache=512
set-variable = sort_buffer=2M
set-variable = record_buffer=2M
set-variable = thread_cache=8
# Try number of CPU’s*2 for thread_concurrency
set-variable = thread_concurrency=8
set-variable = myisam_sort_buffer_size=64M
#set-variable = connect_timeout=5
#set-variable = wait_timeout=5
server-id = 1
[isamchk]
set-variable = key_buffer=128M
set-variable = sort_buffer=128M
set-variable = read_buffer=2M
set-variable = write_buffer=2M

[myisamchk]
set-variable = key_buffer=128M
set-variable = sort_buffer=128M
set-variable = read_buffer=2M
set-variable = write_buffer=2M
#set-variable=key_buffer=16M
[WinMySQLadmin]
Server=C:/mysql/bin/mysqld-nt.exe
user=root
password=********

================好了,代码也优化好了,zend也装好了,基本上服务器配置也OK了~

在开始–运行里输入
net stop iisadmin
运行后然后输入
net start w3svc
然后重新启动一下服务器就OK了~~

注意:本教程主要引用飞刀的原创帖子,但是经过我的测试,发现他介绍的那个加速软件经常会出错,所以我换了加速软件,编写了这个帖子.
另外本人安装完整的php.ini文件在附件那里,大家可以拿去对比

至于phpmyadmin的配置我就不多说了,到处都有教程~:)

一月 19, 2011

hp 交换机配置

Filed under: 乱7八糟 — admin @ 4:47 下午

z     配置模式:以“(config)”开头,能够对设备进行配置和管理,同一时刻仅仅允

许一个管理人员处在配置模式下。此模式下可以同时具有管理模式和登陆模式的功 能。

从管理模式进入配置模式的命令为:configure,即可进入配置模式。 从高级模式退出到低级模式的命令为 exit 或 disable。

3.基本命令

1、 查看操作系统版本及硬件信息

命令:show version作用:查看当前系统版本和状态信息

 

‹ 系统当前版本:

test_5304xl#  show version

Image  stamp:    /sw/code/build/alpmo(m35)

Aug    2 2005 11:27:11

E.10.04

4015

Boot  Image:    Primary

‹ 系统主机名:

‹ 系统 CPU 类型:

‹ 系统内存容量:

‹ 系统启动时间:

‹ 系统当前时间:

‹ 系统端口类型:

‹ 系统序列号:

‹ 系统当前能实现的功能:

2.      配置主机名:

命令:hostname  <name-string>

:其中主机名长度最长为 64 字节

实例:例如需要配置设备的名称为 Blue,则命令如下。

AN(config)#hostname  test_5304xl

Test_5304xl(config)#

3.   配置 VLAN IP 地址:

命令:[no]vlan  <vlan-id> ip  address  <ip-address> <netmask> 或

[no]vlan  <vlan-id> ip  address  <ip-address><mask-bits>或

Vlan  <vlan-id> ip  addess  dhcp-bootp

实例:例如需要对设备划分一个 VLAN 采用两种不同底方式进行配置

Blue(config)#  vlan  1  ip  address  192.168.0.23  255.255.255.0  或

Blue(config)#  vlan  1  ip  address  192.168.0.23/24

查看当前 VLAN 地址命令:

Blue(config)#show  ip  address

4. 配置网关:

配置网关命令:

ip  default-gateway<ip-address>

实例:配置一个缺省的网关

Blue(config)#  ip  default-gateway  192.168.0.1

4.   测试网络联通情况

HP 系列产品提供了 Ping 和 traceroute 来检查网路的联通状况

ping 命令示例:

Blue(config)#ping  192.168.0.1

Traceroute 命令示例:

Blue(config)#traceroute  192.168.10.1

1.2 使用 TELNET 或者 WEB 方式对交换机进行配置

1.2.1 使用 TELNET 方式对交换机进行配置

1.配置 CLI 接口访问

列出当前控制台、串口连接配置。这条命令是显示当前接口访问的参数设置。

语法:show  console

下面图例显示交换机缺省的控制台,串口的配置信息:

 

2.默认情况下入口的 TELNET 访问是允许的。

语法:[no]telnet-server

3.禁止 TELNET 入口访问

语法:Procurve(config)#  no  telnet-server

4.重新允许 TELNET 入口访问

语法:Procurve(config)#  telnet-server

5.远程 TELNET 另外的一台设备并查看该设备的状态。

语法:Procurve(config)#  telnet  192.168.2.35

具体配置手册下载地址:点击下载

一月 18, 2011

python 断点跟踪

Filed under: python — admin @ 7:15 下午

当有异常发生时,可以利用sys.exc_info()获得异常发生点的TraceBack。但正常状态如何获得TraceBack呢?查了很 久资料都没有找到答案。

想来想去,只找到两种不完美的方案:
【方案一】
主动引发一个异常,从而获得其TraceBack。事实上,traceback.extract_stack里就是这么干的:
1 def extract_stack(f=None, limit = None):
2     
3     if f is None:
4         try:
5             raise ZeroDivisionError
6         except ZeroDivisionError:
7             f = sys.exc_info()[2].tb_frame.f_back
8     
这种强行引发异常的方法,肯定会降低性能。
【方案二】
利用sys.settrace,自行对调用堆栈进行跟踪。大致这样来做:
1 def mytrace(frame, event, args):
2     if (event == ’call’):
3         
4     elif (event == ’return’):
5         
6 sys.settrace(mytrace)
这样做,所有的调用都会额外地引发这段自定义处理,显然也会严重影响性能。

一月 17, 2011

python apply()

Filed under: python — admin @ 10:00 上午
#!/usr/bin/env python
def add2(x, y):
        return x+y
print add2(1,2)
print apply(add2, (1,2))

python __call__

Filed under: python — admin @ 9:33 上午

__call__

Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。

换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符。

例如,现在我们要计算重力环境下的自然落体位移。我们知道Sy=(gt**2)/2,那么,我们可以建立一个函数:

def g_dpm(t):

return (9.8*t**2)/2

我们都知道,地球表面的重力加速度约等于9.8m/s**2,这个函数实在没什么技术含量。

慢,头儿说了,我要算的是火星啊¥%#

呃……你能说人家无理取闹么?EAFIFA足球里,我还见过微重力模式的球场,总之,在计算机程序里,很多超现实的需求都有可能。

恩,最简单的办法当然是:

def mar_g_dpm(t):

return (3.92*t**2)/2 #火星表面的重力加速度约等于地球表面的2/5

不过,你真的能保证下次那个可爱的策划不会再设计一个金星场 景?或者木星?或者该死的大魔导师行会开始出售新的魔法卷轴——重力操控?

当然,我们可以这样设计这个函数:

def g_dpm(g, t):

return (g*t**2)/2

但是g相对于t,是一 个稳定得多的数量,基本上,在一次相关运算中,g可以当作常 量。那么,一个可调用对象也许更适合。下面定义这样一个类型:

class g_dpm(object):

def __init__(self, g):

self.g = g

def __call__(self, t):

return (self.g*t**2)/2

计算地球场景的时候,我们就可以令e_dpm = g_dpm(9.8)s = e_dpm(t)。同样的方式,可以很容易的生成其他重力环境下的 自由落地公式

为了弄明白python中__setattr__, __getattr__, __delattr__, __call__的作用,重写dict,扩展其功能

class storage(dict):
    #通过使用__setattr__, __getattr__, __delattr__
    #可以重写dict,使之通过“.”调用
    def __setattr__(self, key, value):
        self[key] = value
    def __getattr__ (self, key):
        try:
            return self[key]
        except KeyError, k:
            return None
    def __delattr__ (self, key):
        try:
            del self[key]
        except KeyError, k:
            return None

    # __call__方法用于实例自身的调用
    #达到()调用的效果
    def __call__ (self, key):
        try:
            return self[key]
        except KeyError, k:
            return None

s = storage()
s.name = “hello”#这是__setattr__起的作用
print s(“name”)#这是__call__起的作用
print s["name"]#dict默认行为
print s.name#这是__getattr__起的作用
del s.name#这是__delattr__起的作用
print s(“name”)
print s["name"]
print s.name

一月 16, 2011

python *,**

Filed under: python — admin @ 11:14 上午

问题:
     Python的函数定义中有两种特殊的情况,即出现*,**的形式。
     如:def myfun1(username, *keys)或def myfun2(username, **keys)等。

解释:
  * 用来传递任意个无名字参数,这些参数会一个Tuple的形式访问。

   **用来处理传递任意个有名字的参数,这些参数用dict来访问。*

应用:
#########################

# “*” 的应用

#########################

>>> def fun1(*keys):
…     print “keys type=%s” % type(keys)
…     print “keys=%s” % str(keys)
…     for i in range(0, len(keys)):
…             print “keys[" + str(i) + "]=%s” % str(keys[i])

>>> fun1(2,3,4,5)

输出以下结果:

keys type=<type ‘tuple’>
keys=(2, 3, 4, 5)
keys[0]=2
keys[1]=3
keys[2]=4
keys[3]=5

#########################

# “**” 的应用

#########################

>>> def fun2(**keys):
…     print “keys type=%s” % type(keys)
…     print “keys=%s” % str(keys)
…     print “name=%s” % str(keys['name'])

>>>
>>> fun2(name=”vp”, age=19)

输出以下结果:
keys type=<type ‘dict’>
keys={‘age’: 19, ‘name’: ‘vp’}
name=vp

Older Posts »

Powered by LINUXQQ   ICP 10203065