Wednesday, 26 October 2011

Note FOR Ruby 1.9 之线程,调试和单元测试

Ruby之线程

  创建一个线程Thread.new, 主线程为Thread.main.Ruby中线程有5中状态:(nil和false状态在inspect下显示为dead,可以用status方法查看线程状态)
  • run: 线程正在执行
  • sleep: sleep或等待IO
  • aborting
  • false: 线程正常结束
  • nil: 线程异常结束
  线程的执行:
words = ["hello", "world", "goodbye", "mars"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Thread.new {
    words.each{ |word| puts word }
}

Thread.new {
    numbers.each{ |number| puts number }
}
  以上代码,两个线程将得不到机会执行.利用join方法,使线程调用者挂起,直到join的线程结束
words = ["hello", "world", "goodbye", "mars"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chars = ["a", "b", "c", "d"]

Thread.new {
    words.each{ |word| puts word }
}.join

Thread.new {
    numbers.each{ |number| puts number }
}.join

chars.each{ |ch| puts ch }
  这样线程变成有序执行了,正确的方法应该如下:
words = ["hello", "world", "goodbye", "mars"]
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

thread1 = Thread.new {
    words.each{ |word| puts word }
}

thread2 = Thread.new {
    numbers.each{ |number| puts number }
}

[thread1, thread2].each { |t| t.join }
  线程优先级:(Thread.pass把执行时间让给其他线程), 设置priority属性,main的priority为0.
  Thread.stop线程挂起, run线程运行
  Mutex类:需要require 'thread'
semaphore = Mutex.new

a = Thread.new {
    semaphore.synchronize {
        1000000.times{ $i += 1 }
    }
}

b = Thread.new {
    semaphore.synchronize {
        1000000.times{ $i += 1 }
    }
}


  Ruby对语句写成多行可能会出现意想不到的结果:
x = (10 +
(2*4))
x = 18
x = (10
+ (2*4))
x = 8
x = (10 \
+ (2*4))
x = 18
  Ruby之irb: irb --help

Ruby之调试

ruby -r debug test.rb

Ruby之单元测试

  1. require 'test/unit'
  2. 继承Test::Unit::TestCase
  3. 方法名要以test开始
  4. setup:在测试代码之前执行
  5. teardown:在测试代码之后执行
附:单元测试相关函数:
  • assert(boolean, message=nil)
  •   Asserts that boolean is not false or nil.
  • assert_block(message="assert_block failed.") {|| ...}
  •   The assertion upon which all other assertions are based. Passes if the block yields true.
  • assert_equal(expected, actual, message=nil)
  •   Passes if expected == +actual.
  • assert_in_delta(expected_float, actual_float, delta, message="")
  •   Passes if expected_float and actual_float are equal within delta tolerance.
  • assert_instance_of(klass, object, message="")
  •   Passes if object .instance_of? klass
  • assert_kind_of(klass, object, message="")
  •   Passes if object .kind_of? klass
  • assert_match(pattern, string, message="")
  •   Passes if string =~ pattern.
  • assert_nil(object, message="")
  •   Passes if object is nil.
  • assert_no_match(regexp, string, message="")
  •   Passes if regexp !~ string
  • assert_not_equal(expected, actual, message="")
  •   Passes if expected != actual
  • assert_not_nil(object, message="")
  •   Passes if ! object .nil?
  • assert_not_same(expected, actual, message="")
  •   Passes if ! actual .equal? expected
  • assert_nothing_raised(*args) {|| ...}
  •   Passes if block does not raise an exception.
  • assert_nothing_thrown(message="", &proc)
  •   Passes if block does not throw anything.
  • assert_operator(object1, operator, object2, message="")
  •   Compares the +object1+ with +object2+ using operator. Passes if object1.send(operator, object2) is true.
  • assert_raise(*args) {|| ...}
  •   Passes if the block raises one of the given exceptions.
  • assert_raises(*args, &block)
  •   Alias of assert_raise. (Deprecated in Ruby 1.9, and to be removed in 2.0).
  • assert_respond_to(object, method, message="")
  •   Passes if object .respond_to? method
  • assert_same(expected, actual, message="")
  •   Passes if actual .equal? expected (i.e. they are the same instance).
  • assert_send(send_array, message="")
  •   Passes if the method send returns a true value.
  • assert_throws(expected_symbol, message="", &proc)
  •   Passes if the block throws expected_symbol
  • build_message(head, template=nil, *arguments)
  •   Builds a failure message. head is added before the template and argu-ments replaces the ’?’s positionally in the template.
  • flunk(message="Flunked")
  •   flunk always fails.

Note FOR Ruby 1.9 之文件,序列化,正则表达式

Ruby之文件

  Ruby中文件相关主要有三个类:IO,File,Dir,FileUtils,其中File继承于IO
IO:foreach, readlines
File:
  • 文件操作:new, open, puts, close, eof......
  • 文件模式:r, r+, w, w+, a, a+, b
  • 判断文件目录是否存在:File.exist?
  • 判断是否目录:File.directory?
  File使用block方式open时,在block结束会自动关闭
File.open('test.txt') { |f|
     p f.gets
}

Dir:foreach
FileUtils: cp, mv, rm, mkdir

Ruby之序列化

  Ruby中序列化有YAML和Marshal,其中Marshal是标准库
YAML: 需要require 'yaml'
  任何对象使用to_yaml方法进行序列化,其中---代表一个新的YAML document,-代表一个元素
["a", "b"].to_yaml
y(["a", "b"])
---
- a
- b

  YAML.dump, YAML.load方法
  to_yaml_properties:选择某些属性进行序列化,其他则忽略
class Yclass
    def initalize(aNum, aStr, anArray)
        @num = aNum
        @str = aStr
        @arr = anArray
    end
    
    def to_yaml_proerties
        ["@num", "@arr"]
    end
end

  这样就只有@num,@arr会序列化
  load_documents加载多个YAML文档
Marshal:同样有dump,load方法,但是某些对象不能够序列化,如果对象有binding,procedure, method,IO的实例,或者singleton对象,在dump时会产生TypeError异常;Marshal中定义marshal_dump来决定哪些属性需要序列化,定义marshal_load在load调用
class Mclass
    def initialize(aNum, aStr, anArray)
        @num = aNum
        @str = aStr
        @arr = anArray
    end
    
    def marshal_dump
        [@num, @arr]
    end
    
    def marshal_load(data)
        @num = data[0]
        @arr = data[1]
        @str = "default"
    end
end

ob = Mclass.new(100, "baron", [1, 3])

  singleton对象的序列化,YAML能够对singleton对象进行序列化,但是load以后就不再是singleton对象了,可以在load之后再将对象转化成singleton对象,例如:
def makeIntoSingleton(someOb)
    class << someOb
        ...
    end
    return someOb
end

  Marshal的版本兼容:Marshal序列化的数据有major,minor号,为存储的第一个和第二个字节,这个和Ruby版本无关,只有相同major,且minor低于时才能load.Marshal提供了两个常量:MAJOR_VERSION和MINOR_VERSION。

Ruby之正则表达式

  Ruby中测试一个正则表达式用=~, 如果匹配,返回匹配字符的位置,如果不匹配,返回nil:
puts /abc/ =~ 'abc'
  创建一个正则表达式有如下几种方法:
  • Regexp.new('^[a-z]*$')
  • /^[a-z]*$/
  • %r{^[a-z]*$}
  match group:
/^(\s*)#(.*)/ =~ ' #comment'
puts $1 << "//" << $2
  sub:
' #comment'.sub(/^(\s*)#(.*)/, '\1//\2')
  match:和=~不同,其返回值为一个MatchData对象
x = /(^.*)(#)(.*)/.match('def myMethod # This is a method')
x.captures.each{ |item| puts(item) }
  其中用to_a或captures返回一个数组,不过to_a第一项为原始字符串。
  如果match使用了group,还可以这样用,第一项为原始字符串:
puts(/(.)(.)(.)/.match("abc")[2])
  pre_match(或者用$`), post_match(或者用$'):
x = /#/.match('def myMethod # This is a method')
puts x.pre_match
puts $`
puts x.post_match
puts $'
  $~代表最后一个MatchData对象
  *和+是greedy match,在其后加上?为最小匹配
  字符串的scan方法找出所有匹配,并且可以传递一个block,字符串有很多方法使用正则表达式,例如slice, slice!, split, sub!, gsub, gsub!
  正则表达式总结:
^beginning of a line or string
$end of a line or string
.any character except newline
*0 or more previous regular expression
*?0 or more previous regular expression (non greedy)
+1 or more previous regular expression
+?1 or more previous regular expression (non greedy)
[]range specification (e.g. [a-z] means a character in the range ‘a’ to ‘z’)
\wan alphanumeric character
\Wa non-alphanumeric character
\sa whitespace character
\Sa non-whitespace character
\da digit
\Da non-digit character
\ba backspace (when in a range specification)
\bword boundary (when not in a range specification)
\Bnon-word boundary
*zero or more repetitions of the preceding
+one or more repetitions of the preceding
{m,n}at least m and at most n repetitions of the preceding
?at most one repetition of the preceding
|either the preceding or next expression may match
()a group

Sunday, 23 October 2011

Note FOR Ruby 1.9 之Symbol, Module

Ruby之Symbol

  Symbol.all_symbols查看
  Ruby可以在运行是动态增加和删除一个方法,使用define_method,remove_method,使用method_defined?来确定是否定义了某方法

Ruby之Module

  Ruby中Module类似于Class,其superclass为Object,class为Class,只是Module不能实例化,不能继承,但是可以让一个类继承与一个module。Module主要有两个作用,一是作为命名空间;二是,Ruby中是单继承关系,Module用来解决多继承问题,Module对外是不可见。Ruby库中包含Math,Kernel模块
module MyModule
    A = "a"

    def method
    end

    def MyModule.moduleMethod
    end
end

MyModule::A
MyModule.moduleMethod

include MyModule
method
  include只是将module中的instance method导入,而模块函数则没有;类如果包含了模块,则类和类实例都可以访问模块实例方法
  模块的局部变量是对外不可见的,即使是外部调用模块实例方法,其方法引用局部变量也不可以:
x = 1

module Foo
     x = 50

     def no_bar
         return x
     end

     def bar
         @x = 1000
         return @x
     end

     puts "In Foo: x = #{x}"
end

include Foo
puts x
#puts no_bar
puts bar

  module可以有实例变量,模块函数可以访问:
module X
    @instvar = "@instvar"
    
    def self.aaa
        puts @instvar
    end
end

X.aaa

module X
    @instvar = "@instvar"
    @@classvar = "@classvar"
    def amethod
        @instvar = 10
        puts @instvar
    end
    
    def self.aaa
        puts @instvar
    end
end

include X
X.aaa
puts @instvar
amethod
puts @instvar
@instvar = "hello world"
puts @instvar
X.aaa
puts @@classvar
@@classvar = "bye"
puts @@classvar
可以使用X.instance_variables和self.instance_variables查看变量信息

  如果两个module有相同的实例方法,则取决于include的顺序,会引入后include的方法。为避免覆盖,使用alias newMethodName methodName
  require用于引用一个文件,其搜索路径为$:,或者使用load方法
require “mod.rb"和load("mod.rb", true)的区别:
  • load把代码以一个匿名模块导入
  • require只load文件一次
  Ruby已有的模块:
  • Comparable: 需要实现<=> 并且根据它实现< <= == >= > between?
  • Enumerable: 需要实现each
  • FileTest: 访问File类
  • GC: Ruby的垃圾回收,ObjectSpace模块
  • Kernel: 由Object类包含,build-in方法
  • Math
  • ObjectSpace: 垃圾回收相关,可以遍历当前对象
  • Precision
  • Process
  • Signal
  module_function用于指定一个方法同时为模块方法和模块实例方法
  extend对对象进行模块的扩展,而不影响其类,如果扩展的方法和类方法相同,则覆盖类方法:
module MyModule
    def amethod
    end
end

class MyClass
    def method
    end
end

ob = MyClass.new
ob.extend(MyModule)
ob.amethod

ob.freeze用于禁止extend,可以用frozen?来测试

Note FOR Ruby 1.9 之异常,Block

Ruby之异常处理

  Ruby中异常类为Exception,其中$!存储了最后一次异常
begin
rescue <Exception Class> => exc
else #no exception
ensure
end

  除此之外,Ruby还有一种类型的异常是Errno模块,利用Errno.constants和Errno::constant name::Errno查看相关信息.
  retry重新执行begin...end语句,raise重新抛出异常.
  • raise :抛出RuntimeError或者$!
  • raise "Message"
  • raise ZeroDivisionError
  • raise ZeroDivisionError.new("Message“)
  Exception.backtrace

Ruby之Block

  Block不是对象
  Proc,proc和lambda用来从block创建一个对象:
  • a = Proc.new{|i|}
  • b = lambda{|i|}
  • c = proc{|i|}
通过call方法调用,例如a.call(1),3者的一个区别在于Proc在调用是不会检查参数个数是否匹配,而lambda和proc会。
  Ruby中block是闭包(在block创建时能够存储本地变量的值)
1 x = "hello world"
2
3 ablock = Proc.new { puts(x) }
4
5 def aMethod(aBlockArg)
6     x = "goodbye"
7     aBlockArg.call
8 end
9
10 puts x
11 ablock.call
12 aMethod(ablock)
13 ablock.call
14 puts x

  block和实例变量:
1 aClos = lambda{
2     @hello << " baron"
3     puts "in #{self} object of class #{self.class}, @hello = #{@hello}"
4 }
5
6 def aFunc(aClosure)
7      @hello = "hello"
8     aClosure.call
9 end
10
11 class X
12      def y(b)
13           @hello = "I say"
14           puts "in X.y #{self} object of class #{self.class}, @hello = #{@hell o}"
15           b.call
16      end
17 end
18
19 aFunc(aClos)
20
21 x = X.new
22 x.y(aClos)

  block和局部变量:
1 x = 3000
2
3 c1 = lambda{ return x + 100 }
4 c2 = lambda{ |z| return z + 100 }
5 c3 = lambda{ |x| return x + 100 }
6
7 def foo
8      [1, 2].each { |i| c = i }
9      #c在这里不可见
10 end

  defined?用于查看变量类型
  yield:执行传给方法的block
1 def aMethod(str)
2      yield(str)
3 end
4
5 aMethod("Goodbye"){|x| puts(x) }

  方法接受一个带&的参数时,则传入一个block:
1 def aMethod(&p)
2      yield
3 end
4
5 myproc = lambda{puts "hello"}
6 aMethod{puts "goodbye"}
7 aMethod(&myproc)

  block_given?判断有无传入一个block
  {}的block比do...end优先级高:
foo bar do ... end相当于foo (bar) do ... end
foo bar {} 相当于foo (bar{})

  方法返回一个block
1 def calcTax(taxRate)
2      return lambda {
3          |subtotal|
4          subtotal * taxRate
5      }
6 end
7
8 salesTax = calcTax(0.10)
9 vat = calcTax(0.175)
10
11 puts salesTax.call(10)
12 puts vat.call(10)

Sunday, 16 October 2011

Note FOR Ruby 1.9 (3)

14.Ruby之Method:
类方法:def <CLASSNAME>.<classMethodName>
Ruby中类除了类变量外,还可以拥有类实例变量:
class MyClass
     @@classvar = 1000
     @instvar = 1000

     def MyClass.classMethod
         puts "@@classvar = #{@@classvar}, @instvar = #{@instvar}"
     end

     def instanceMethod
         puts "@instvar = #{@instvar}"
     end
end

myclass = MyClass.new
MyClass.classMethod
myclass.instanceMethod

*可以使用instance_get_variable方法获取变量值
*在Ruby中类也是一个对象,其是Class类的实例.
*Ruby中new方法为类方法,其创建一个对象并调用initialize类实例方法初始化.

15.Ruby之Singleton方法:
Singleton方法是指一个方法只属于一个类实例,而不属于整个类,所以在Ruby中类库中有很多Singleton,因为每个类都是Class类的实例:
p IO.singleton_methods
定义一个singleton方法:
def myclass.objectMethod
end

查看对象是否拥有某个singleton方法可以调用respond_to?(:Symbol)

Singleton类:
其定义为定义一个类对象的类:
ob = Object.new

class << ob
     def blather(aStr)
         puts "blather #{aStr}"
     end
end


Singleton类方法:
class MyClass
     class << self
         def methodA
         end
     end
end

class << MyClass
     def methodB
     end
end

p MyClass.singleton_methods


16.Ruby之public,private,protected:
public, private, protected是Module类的方法
class MyClass
     private
         def priv
         end

     protected
         def prot
         end

     public
         def pub
         end

     def useOb(anOb)
         anOb.pub
         anOb.prot
         #anOb.priv
     end
end

myclass1 = MyClass.new
myclass2 = MyClass.new
#myclass1.priv
#myclass1.prot
myclass1.pub
myclass1.useOb(myclass2)

protected的作用是对在相同类型的对象2在对象1的作用域范围内是可见的,在继承关系链中同样适用
虽然private方法在外部不能调用,但是可以用send方式:
class X
     private
         def priv
         end
end

ob = X.new
ob.send(:priv)


17.Ruby之内部方法
class X
     def x
         def y
         end
     end
end

ob = X.new
#ob.y
ob.x
ob.y

直接调用内部方法会出错,但是如果调用过一个方法其包含内部方法,则会将其内部方法暴露到外部作用域

18.Ruby之不定参数:
def aMethod(a = 10, *b)
     return a, b
end

p aMethod(1, 2, 3, 4)


19.Ruby之特殊的整数:
Ruby中每个字符串和浮点数都是不同的对象,例如:a = "hello" b = "he" + "llo" 其中a和b是不同的对象,然而对于整数,对同一个整数而言,它们是相同的对象: a = 10 b = 8 c = b + 2 其中a和c指向同一对象
Ruby中以!号结尾的方法(包括<<字符串连接)会改变对象本身,否则返回一个新的对象

20.Ruby之拷贝和引用:
equal?用来判断是否同一对象
在Ruby核心模块中==用来判断是否为同一对象,但在一些类中被重写,例如String.

Wednesday, 12 October 2011

Note FOR Ruby 1.9 (2)

10.Ruby之Array,Hash,Set,Matrix/Vector:
  • Array:
  • 创建一个Array:
    arr = Array.new(3, "baron")
    for i in arr
         print " " << i
    end

    Array比较<=>:
    小于返回-1,等于返回0,大于返回1
    改写比较方式,可以使用<, ==, >进行比较:
    class MyArray < Array
         include Comparable

         def <=>(anotherArray)
             self.length <=> anotherArray.length
         end
    end

    myarr1 = MyArray.new([0, "ab", "c"])
    myarr2 = MyArray.new([1, 2])

    p myarr1 <=> myarr2

    Array.sort:
    arr2 = ["one", "b", "abcde", 1, 3]
    sort_arr2 = arr2.sort {
         |a, b|
         a.to_s <=> b.to_s
    }
    p sort_arr2

    Array运算:
    1. &: 交
    2. +: 并
    3. -: 差
    4. <<: 添加
    Array.flatten:
    arr = [1, 2, 3, [4, 5]]
    p arr.flatten

  • Hash:
  • 创建Hash:
    hash = Hash.new("Default")
    hash['b'] = "ccc"
    p hash
    p hash.default

    Hash.sort:
    用法和Array类似
11.Ruby之循环
  • for ... in ... do
    end
  • ... .each do |...|
    end
  • while ... do
    end
  • begin
    end while ...
  • until ... do
    end
  • begin
    end until ...
  • loop {
    }
12.Ruby之条件
  • 条件运算符,Ruby有两套,而且优先级不同,最好不要混用
    1. and, or, not
    2. &&, ||, !
    3. === 相当于 include?
  • if ... then ... elsif ... then ... else ... end
  • begin ... end if ...
  • begin ... end unless ...
  • case ... when ... else ... end
    case返回值为when的最后一条语句
  • catch,throw:
    catch (Symbol) {
    ...
    throw Symbol
    ...
    }
13.Ruby之Enumerable:
Ruby中的Array已经包括Enumerable模块,其中包含了include?, collect, min, max方法:
arr = [1, 2, 3, 4, 5]
p arr.include?(3)
p arr.collect{ |i| i * i}
p arr.min
p arr.max

可以自定义min, max的行为:
hash = {"one" => "Monday", "two" => "Tuesday"}
p hash.min{|a, b| a[1].length <=> b[1].length}

each, yield用法
class MyCollection
     include Enumerable

     def initialize(someItems)
         @items = someItems
     end

     def each
         @items.each { |i| yield(i) }
     end
end

things = MyCollection.new(['x', 'yz', 'defgh', 'ij', 'klmno'])
p things.min
p things.max
p things.collect{ |i| i.upcase }
当调用min,max,collect等方法时,其会调用each方法

Saturday, 8 October 2011

Note FOR Ruby 1.9 (1)

  1. Ruby之引号:
    • 单引号:不进行转义
    • 双引号:转义字符和嵌入表达式计算
    • `:作为system的命令执行
    • 自定义字符串分割符:
    • %Q/string/: 代表双引号字符串
      %/string/: 代表双引号字符串
      %q/string/: 代表单引号字符串
      %w/ / :单引号字符串Array
      %W/ / :双引号字符串Array
      %r| | : 正则表达式
      %s/ /: symbol
      %x/ /: 命令
      另外%Q(%q)后可以选择其他非字母数字字符,例如#, [, {
    puts 'sample #{1+1}\n'
    puts "sample #{1+1}\n"

    sample #{1+1}\n
    sample 2

  2. Ruby之注释:
  3.   有#和=begin/=end两种
  4. Ruby之变量:
    • var 局部变量
    • $var 全局变量
    • @var 类实例变量
    • @@var 类变量
    • Class::VAR 类常量
  5. Ruby之字符串:
    • 字符串连接:三种方式: << , + 或者空格隔开
    • 多行字符串:
    • <<LABEL
      LABEL

      <<'LABEL' 代表单引号字符串
      LABEL

  6. Ruby之main:
  7.   程序在运行时,Ruby会创建一个main对象 puts self
    puts self.class
    main
    Object
  8. Ruby之new, initialize, super:
  9. class People
        def initialize(name)
            @name = name
        end

        attr_reader :name
    end

    class Male < People
        def initialize(name)
            super
        end
    end

    class Female < People
        def initialize(name, beauty)
            super(name)
            @beauty = beauty
        end

        attr_reader :beauty
    end

    baron = Male.new('Baron')
    puts baron.name
  10. Ruby之inspect:
  11.   很好的调试工具
    puts baron.inspect OR p baron

    #<Male:0x1267e90 @name="Baron">
  12. Ruby之类实例属性访问:
    • 编写访问函数
    • def get_name
          return @name
      end

      def set_name(name)
          @name = name
      end
      baron.set_name 'PAN'
      puts baron.get_name
    • =号赋值
    • def name
          return @name
      end

      def name=(name)
          @name = name
      end

      baron.name = 'PAN'
      puts baron.name
    • reader和writer
    • attr_reader :name
      attr_writer :name
      OR attr_accessor :name
  13. Ruby之Object:
  14.   Ruby中所有类继承于Object,可以通过object_id查看实例id
    cls = baron.class
    begin
        cls = cls.superclass
        puts cls
    end until cls == nil

    People
    Object
    BasicObject

Thursday, 6 October 2011

Arch linux 64-bit 安装小记

  上个星期末终于痛下决心,为了4G内存,全盘格掉,只安装Arch 64-bit,从此进入64位时代。这个是安装小记,之所以称为小记,其中并没有详细安装过程,只是做些提要以便后用。
  当然,首先下安装映像,去arch官网down个就是了,一般我选net-install形式的,制作USB启动盘。启动后/arch/setup进入安装界面,按照提示进行就是了,很方便的。
  安装X,安装gnome,这里是gnome3了。修改”/etc/inittab”,主要是默认启动到X,并修改登录方式。查看和修改”/etc/rc.conf”和”/etc/fstab”,将hal添加到DAEMONS中。详细查看arch wiki就是了。
  中文化:修改”/etc/locale.gen”,安装WenQuanYi字体。
  安装VIM,配置。
  添加AUR:
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch
  安装yaourt。
  无线网卡:BCM4312的安装broadcom-wl,模块名为wl,安装networkmanager,dhcpcd,相应修改”/etc/rc.conf”,注掉network,b43等。
  cpu模式配置,cpufreq。
  输入法ibus。
  gnome3下把gconf-editor改成dconf-editor了。
  编译新内核:
  1. tar 内核源码到用户目录
  2. zcat /proc/config.gz > .config
  3. make menuconfig
  4. make && make modules_install
  5. cp arch/x86/boot/bzImage /boot/vmlinuz
  6. mkinitcpio -k 版本号 -g /boot/kernel.img
  7. 修改/boot/grub/menu.lst
  最后几个实用工具:
  1. htop,查看内存,CPU实用情况。
  2. mocp,很好的music播放器。
  3. bash-completion,bash下补全。

Win7下USB烧linux2.6.36 for 飞凌ok6410A

下面记录下win7下USB烧linux2.6.36 for 飞凌ok6410A大法:(官方的说法是提供的工具对Win7兼容性不好,最好XP,我表示很伤心……)
  1. SDBoot制作:
  2.   格式化SD卡为fat32,管理员下运行SD_write.exe,以为format会调用diskpart,然后把mmc.bin烧到SD卡中,我觉得这一步就是把启动代码写到启动扇区里了,用DD命令应该可以替代,有时间研究下。这个猜想官方没有给出证实。
  3. 串口启动:
  4.   板子插电,插串口,由于这里用的串口转USB for PC,所以需要装相关驱动,这个是找商家要的,原来居然没给,有个专门for win7的驱动。之后会识别出一个串口,打开DNW,连接相应串口,USB Address设为57e00000。
  5. 烧UBoot:
  6.   板子SD启动模式,在autoboot下按空格停下,输入”dnw 50008000″设置usb传输地址,此时插上USB线,会出现新设备,需要安装相关驱动,这里有两点需要注意:1.不需要像手册上说的需要transmit mmc.bin,这玩意应该就只是SD启动时用。2.只有在配置了dnw传输地址才会识别USB设备,这点很关键。   下面
    transmit uboot nand erase 0 100000 nand write.uboot 50008000 0 100000
  7. 烧内核:
  8.   配置nandflash启动,autoboot下暂停。
    dnw 50008000 transmit zImage nand erase 100000 500000 nand write.e 50008000 100000 500000
  9. 文件系统:
  10. dnw 50008000 transmit cramfs nand erase 600000 10000000 nand write.e 50008000 600000 10000000
大功告成,reset后出现久违的linux,QT的KDE貌似,有点丑,呵呵!

win7下搭建git server小记

  1. git支持ssh协议,所以首先作为git server的机器要配置sshd.这里就没有用cygwin了,用的是copssh.安装完后,在control panel中添加一个用户作为Activated user。去掉“Password Authentication”选项,这里用公钥认证就好了。现在在另一台机器上,安装有ssh客户端,(哈哈,这台机器上用了cygwin,也可以用putty),用ssh-keygen生成一对密钥对,把公钥文件命名为“authorized_keys”放在copssh安装目录下home/< user name >/.ssh/下,这样在客户端就可以用“ssh < user name >@< ip >“远程登录测试(windows防火墙会阻拦sshd的通信,需要配置下防火墙)
  2. 两台机器上都安装git,用msysgit,安装之后需要将git的执行路径添加到copssh的PATH路径中(etc/profile):
    syspath=`/bin/cygpath -S`
    winpath=`/bin/cygpath -W`
    gitpath=`/bin/cygpath /cygdrive/d/Git/cmd`
    export PATH=”/bin:$syspath:$winpath:$gitpath:”
    另外msysgit缺少几个命令,需要自己添加git-receive-pack,git-upload-archive,git-upload-pack,例如:
    #!/bin/sh
    git receive-pack $*
    为了方便把远程登录的起始目录项作为存放代码的目录
  3. 准备工作已经就绪,在git server上创建一个代码仓库

  4. mkdir project.git
    git –bare init
  5. 客户端可以如下添加代码和提交

  6. git remote add origin < user name >@< ip >:project.git
    git push origin master
其他git用法请参考git 手册
这样就搭建起了一个自己的git server。

Simple example for OAuth

之前一篇文章介绍了OAuth协议的基本概念,这篇就来举个具体的应用实例吧,照旧还是用dropbox。
  1. 每一个使用dropbox api的应用都可以在官网上申请到一对(key,secret)信息,假设为:
  2. Client Identifier = dpf43f3p2l4k3l03 Client Shared-Secret = kd94hf93k423kf44 (HMAC-SHA1会用到)
  3. Temporary Credential Request过程,dropbox提供的URL为https://api.dropbox.com/0/oauth/request_token,是建立在安全传输协议上的。
    • client生成请求字符串:
    • GET&https%3A%2F%2Fapi.dropbox.com%2F0%2Foauth%2Frequest_token&   oauth_consumer_key%3Ddpf43f3p2l4k3l03%26   oauth_nonce%3D01408443%26   oauth_signature_method%3DHMAC-SHA1%26   oauth_timestamp%3D1298386060%26   oauth_version%3D1.0
    • 用shared-secret对此字符串加密并签名(末尾加了一个'&')
    • 最终的请求格式如下:
    • Authorization: OAuth realm="",   oauth_nonce="01408443",   oauth_timestamp="1298386060",   oauth_consumer_key="dpf43f3p2l4k3l03",   oauth_signature_method="HMAC-SHA1",   oauth_version="1.0",   oauth_signature="N0NYBBJn956BZ16bWH2gEjrqYqM%3D"
    • server返回:
    • oauth_token_secret=u245rhlyg6vlqlf&oauth_token=q3n1yqeeujpv04z
  4. 重定向resource owner到认证URL下进行身份的认证,dropbox的认证URL为:https://www.dropbox.com/0/oauth/authorize。
  5. https://www.dropbox.com/0/oauth/authorize?oauth_token=q3n1yqeeujpv04z&oauth_callback=http%3A%2F%2Fwww.fakeang.me oauth_callback指定了在验证完resource owner之后跳转的URL,这里会重定向到我的blog地址 http://www.fakeang.me/?uid=10537346&oauth_token=q3n1yqeeujpv04z uid是对resource owner的verifier信息
  6. Access Token Request过程,和之前的Temporary Credential Request认证过程比较相似,dropbox的验证地址为:https://api.dropbox.com/0/oauth/access_token
  7. 请求格式会增加两项:
    • oauth_token=q3n1yqeeujpv04z
    • oauth_verifier=10537346
  8. 用shared-secret+‘&’+(oauth_token_secret)u245rhlyg6vlqlf加密
  9. 返回用于访问resource的token和密钥访问资源时和Temporary Credential Request过程也类似,只不过会使用access token
最后附上OAuth1.0协议RFC文档地址:RFC5849

OAuth 学习小记

  OAuth协议在现在有很多应用,比较感兴趣,学习下;详细见OAuth官网
  1. OAuth简介:
  2.   OAuth定义了三个角色:client/server/resource owner.就传统认证方式而言,是client-server一对一的认证方式,client和resource owner几乎是对等的地位,client要获得server的认证必须知道resource owner的全部信息,例如:username/password,一旦client获得server的认证,这样资源拥有者无法限制client的权限了。但是,如果出现了以下情况:A是资源拥有者,A将资源授予C,而B需要访问该资源,但是A又不愿意让B知道A和C之间的认证方式,那么如何实现这种三方认证呢。
      OAuth是对第三方访问resource owner的资源的一个权限保护,用于HTTP(S)协议资源访问。
  3. OAuth认证过程简介:
  4. 2-Legged, 3-Legged, n-Legged,;)这个就不解释了。
    OAuth使用三种类型证书:client credentials, temporary credentials, and token credentials.
    client credentials: consumer key and consumer secret
    temporary credentials: request token and secret
    token credentials: access token and secret
      这里以dropbox为例,假设A dropbox user/B dropbox第三方应用/C dropbox server.A需要用B去访问自己存在C上的资源,但B不应该知道A的用户名和密码。
      首先,B会拿到C给的一个consumer key和consumer secret;B请求C一个request token。
      接着,B会用这个request token重定向A到C提供的一个URL去认证身份。A通过C的认证后,会被告知B发出一个访问请求,需要允许或者禁止。如果允许,C将此认证后的request token通知B,B用它交换得到access token,这是访问A在C上资源的令牌。
      这样,B就可以不用知道A和C之间的令牌,而获取到A在C上的资源访问权限了。
  OAuth的精妙之处在于在HTTP这样一个不安全的通信环境下保证了通信的安全性。并能够防止man-in-the-middle attack (MITM),eavesdropping等等,基于HMAC-SHA1/RSA-SHA1。OAuth协议是一种authorization delegation protocol(认证-授权)。
  1. OAuth与普通认证方式的差异:
  2.   最通常的认证方式是username/password认证,而对于OAuth这种可以提供多方认证就不能简单的依赖于传统的这种方式了,它主要依赖于consumer key(secret)/token key(secret)。令牌取代了实际的用户名和密码,而使得第三方不需要知道实际的用户名和密码。   OAuth中有两种令牌:request token/access token。两个通道:front-channel(用于User进行请求认证)/back-channel(client/server信息交换)。
  3. OAuth的数据完整性和可认证性:
  4.   OAuth利用HASH算法保证了传输数据的完整性,再加入双方共享的秘密信息作为信息来源的可认证。能够有效的防止数据的伪造和篡改,详见HMAC-SHA1 base64 with sha-1

    import binascii
    import hashlib
    binascii.b2a_base64(hashlib.sha1('test').digest())

    base64 with HMAC-SHA1

    import hmac
    import hashlib
    import binascii
    bin = hmac.new('baron', 'test', hashlib.sha1)
    binascii.b2a_base64(bin.digest())
  5. RSA-SHA1在OAuth中的应用:
  6.   consumer用私钥对请求信息签名,server用公钥验证请求,在这里私钥的安全性是整个RSA-SHA1安全性的唯一保证。
  7. 时间戳Timestamp:
  8.   为了抵御重放攻击,OAuth利用nonce(我比较喜欢seed这个词)和时间戳,nonce和信息一起被签名的,防止被篡改。
  总的来看,OAuth同时运用了对称加密,非对称加密,数字签名等来保障认证的安全性。

dropbox api用法小记

  首先用到了Socksipy,支持http, sock4, sock5 proxy,可以方便的通过SOCK5去访问dropbox相关链接。

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, proxy_host, proxy_port)
socket.socket = socks.socksocket

  这样就可以走代理了,在用dropbox api之前需要去申请一个APP KEY,需要写到配置文件中去。用auth获得access token:

from dropbox.auth import Authenticator

config = Authenticator.load_config('config.ini')
auth = Authenticator(config)

user_name = # dropbox username
user_password = # dropbox password

access_token = auth.obtain_trusted_access_token(user_name, user_password)

  拿到token以后就可以自由发挥了,这里试了下取到文件目录信息:

from dropbox.client import DropboxClient

client = DropboxClient(config['server'], config['content_server'], config['port'], auth, access_token)
client.metadata('dropbox', '').body

  1. 获取账户信息:
  2. from dropbox.client import DropboxClient client = DropboxClient(config['server'], config['content_server'], config['port'], auth, access_ token) print client.account_info().body
  3. 文件相关API:
  4. 获取thumbnail: thumb = open("vim.png", "wb") thumb_data = client.thumbnail('dropbox', '/vim.png', 'large').read() thumb.write(thumb_data) thumb.close() 获取文件: f = open("vim1.pdf", "wb") f_data = client.get_file('dropbox', '/testfile/vim1.pdf').read() f.write(f_data) f.close()
  除此之外还有文件上传、移动、删除以及创建文件夹,就不一一列举了。
PS:dropbox对path会有处理,比如传这种路径:“/../../../vim1.pdf”,会生成在“/”下面;所有请求都是对相应的URL进行GET/POST操作,例如:调用file_move就是对URL:https://api.dropbox.com//fileops/move的POST请求。