2014年10月

while进行批量ssh操作的问题

现在有这样一个场景,本机到一批机器的ssh key都已经打通,想用while循环到这批机器上执行命令,看下面的shell代码

#!/bin/sh

while read ip
do
    echo "ssh connecting to $ip"
    ssh $ip 'ls'
done < data

执行后会发现,只有一台机器成功ssh,并且执行了命令。很奇怪,再来看一段代码

#!/bin/sh

while read ip
do
    echo "ssh connecting to $ip"
    read
done < data

data文件里面有10个ip,但是实际echo却只有5个echo

ssh connecting to 192.168.1.1
ssh connecting to 192.168.1.2
ssh connecting to 192.168.1.3
ssh connecting to 192.168.1.4
ssh connecting to 192.168.1.5

如何解释以上的现象呢?问题还是while的重定向,在while进行重定向的时候,实际是一次把所有的内容都读取了,然后每次调用read的时候读取到换行或者EOF就结束。第二个例子在while循环里的read会从buffer里读取去,然后程序就没有block住,直接往下走了。

再来解释第一个代码,ssh的时候存在一个“尝试从终端读入的操作”,所以会把buffer后面的内容(第一个ip以外的剩余内容)都读入,这就导致只有一个ssh执行。

Python下unicode和string编码

问题

#!/usr/bin/python
# -*- coding: utf-8 -*-

s = "你好"
s.encode("utf-8")

运行结果报错

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

报错原因

在python里面,编码和解码的关系如下:

unicode -> string 编码
string -> unicode 解码

上面的s变量其实是string类型,如果尝试对s进行encode,那么必须对s变量进行解码成unicode,然后再编码成string。但是在s变量解码的过程中,python会根据系统默认的解码方式进行解码,根据报错可以看出是python默认的解码方式是"ascii",sys.getdefaultencoding()可以查看。但是因为文件开头指定了s变量又是utf-8的编码方式,所以就冲突了,做法就是在编码之前指定"utf-8"进行解码。

如何判断某个字符串的编码?

isinstance(s, str) 用来判断是否为一般字符串

isinstance(s, unicode) 用来判断是否为unicode
#!/usr/bin/python
# -*- coding: utf-8 -*-

string = "你好"
string.decode('utf-8').encode("utf-8")

还有一种方式就是修改python默认编码解码方式

import sys
reload(sys)
sys.setdefaultencoding('utf-8')