列表的基本操作。
比如构造一个1、3、5、7...
的列表,使用什么方法呢。这是比较笨的方法。
L = []
i = 1
while i <= 99:
L.append(i)
i = i + 2
print (L)
# or
j = 1
k = 0
while j <= 99:
L[k] = j
j = j + 2
k = k + 1
print (L)
效果虽然一样,但是还是有点问题的。问题之一就是效率,写的太啰嗦了。
切片就是在列表中,以下标的方式读取元素的方法。举个例子
L = ["1",'2', '3', '4']
print L[0:2] # 打印从第0个到第2个的元素
# 等价于
print L[:2]
# 还可以
print L[1:2] # 从第1个元素到第2个元素
# 还可以
print L[-1] # 这个打印的是倒数第一个元素 4
请看下面的例子:
>>> l = ['1','2','3','4']
>>> print l[-1]
4
>>> print l[:-1] # 从正数第一个取到倒数第一个(但是并不会取到)。
['1', '2', '3']
>>> print l[-1:] # 从倒数第一个取,取到最后,只有他自己
['4']
>>> print l[-3 :-1] # 从倒数第一取到倒数第1,
['2', '3']
>>> print l[-2:] # 从倒数第2取到最后
['3', '4']
>>>
首先新建一个包含100个元素的列表。
>>> yubo = list(range(100))
>>> print (yubo)
详情可以参考注释。
>>> hechun = ['yubo','hehe','haha']
>>> print (hechun)
['yubo', 'hehe', 'haha']
>>> hechun.append(123)
>>> print (hechun)
['yubo', 'hehe', 'haha', 123]
# 在指定位置插入元素
>>> hechun.insert(1, 'csl')
>>> print (hechun)
['yubo', 'csl', 'hehe', 'haha', 123]
# 删除指定元素,其元素已不在list中
>>> del hechun[1]
>>> print (hechun)
['yubo', 'hehe', 'haha', 123]
# 使用pop方法,并可以继续访问这个值
>>> tmp = hechun.pop()
>>> print (tmp) #默认是最后一个元素
123
>>> tmp = hechun.pop(0) #可以指定元素位置
>>> print (tmp)
yubo
>>> print (hechun)
['hehe', 'haha', '123']
>>> hechun.remove('haha')
>>> print (hechun)
['hehe', '123']
这里有排序、打印、长度等操作
# 排序
>>> print (hechun)
['hehe', '123']
>>> hechun.sort()
>>> print (hechun)
['123', 'hehe']
#反序
>>> hechun.sort(reverse=True)
>>> print (hechun)
['hehe', '123']
#使用sorted()可以保存原来列表的内容,你可以将新的列表
#复制给新的列表
### 倒序打印列表
>>> print (hechun)
['hehe', '123']
>>> hechun.reverse()
>>> print (hechun)
['123', 'hehe']
操作列表,就是在列表上执行某一特定操作。
# 复制A,全复制
# 你对原列表的改动,可以影响复制后的列表
>> yubo = ['123','hello','world']
>>> hechun = yubo
>>> yubo.append('456')
>>> print (yubo)
['123', 'hello', 'world', '456']
>>> print (hechun)
['123', 'hello', 'world', '456']
# 复制列表,但对于复制后的不影响
>>> test = yubo[:]
>>> print (yubo)
['123', 'hello', 'world', '456']
>>> yubo.append('789')
>>> print (yubo)
['123', 'hello', 'world', '456', '789']
>>> print (test)
['123', 'hello', 'world', '456']
字典里面可以储存更多的信息,理解它后,你就可以更加准确的为各种真实物体建模了。字典是一系列键-值
对,
# 访问元素
>>> alien_0 = {'color': 'green','point':5}
>>> ptinr(alien_0['color'])
>>> print(alien_0['color'])
green
# 加入有这么一个游戏,是你现在获得的point
# 注意str函数,这是将列表、元组或者字典里面的字符转化为字符串
>>> new_point = alien_0['point']
>>> print("You just earned" + str(new_point) + "points!" )
You just earned5points!
# 添加元素,注意,字典添加元素使用[]添加进去的
>>> alien_0['x_position'] = 0
>>> alien_0['y_position'] = 25
>>> print(alien_0)
{'color': 'green', 'y_position': 25, 'x_position': 0, 'point': 5}
# 修改某一键值
>>> alien_0['color'] = 'yellow'
>>> print(alien_0)
{'color': 'yellow', 'y_position': 25, 'x_position': 0, 'point': 5}
# 删除键, 注意,永远消失
>>> del alien_0['point']
>>> print(alien_0)
{'color': 'yellow', 'y_position': 25, 'x_position': 0}
# 遍历字典 items()
>>> alien_0.items()
[('color', 'yellow'), ('y_position', 25), ('x_position', 0)]
#使用for, 分别得到键、值.注意,对于数值型的字符,注意转换
>>> for attr, value in alien_0.items():
... print("\n attr: " + attr)
... print("\n value: " + str(value))
...
attr: color
value: yellow
attr: y_position
value: 25
attr: x_position
value: 0
# 只得到键, 实际上,它得到一个列表
>>> for value in alien_0.keys():
... print(str(value))
...
color
y_position
x_position
#只得到值,返回一个列表
for value in alien_0.values():
# 多个字典在一个字典中
# 注意这里,将三个字典放入一个字典中,使用列表包围起来
alien_0 = {'color': 'green', 'point':5}
alien_1 = {'color': 'yellow','point':10}
alien_2 = {'color':'red', 'point': 15}
aliens = [alien_0, alien_1, alien_2]
print(alines)
# 字典里储存列表
pizza = {
'crust': 'thick',
'toppings': ['mushroom', 'extra sheese'],
}
print("You ordered a " + pizza['crust'] + "-crust pizza" +
" with the following the topping:")
for topping in pizza['toppings']:
print("\t" + topping)
# 再看一个简单的例子
favorite_languages = {
'yubo' : ['c,','python'],
'hechun' : ['math', 'c', 'shell'],
'hecheng' : ['shell'],
}
for name, language in favorite_languages.items():
print("Person's name is " + name.title())
for lan in language:
print("\t" + str(lan) + " ")
# 字典里面嵌套字典
下面这段代码综合利用了上面的知识:
# 注意字典的这样输入法
favorite_languages = {
'yubo': 'pytthon',
'hechun': 'math',
'xiaoxiao': 'c',
}
friends = ['yubo', 'hechun']
# 可以使用sorted(favorite_languages.keys())进行排序后的输出
for name in favorite_languages.keys():
print(name.title())
if name in friends:
print(" Hi " + name.title() +
", i see you favorite languages is " +
favorite_languages[name].title() + "!")
用户输入填充字典, 有些东西需要raw_input()函数实现。
responses = {}
polling_active = True
while polling_active:
name = raw_input("\n What is your name? ")
response = raw_input("Which mountain would you like to climb someday?")
# 将答案存在字典中, 我自己这里写错了
responses[name] = response
# 看看是否还有其他人参与调查问卷
repeat = raw_input("Would you like to let another people response?")
if repeat == 'no':
polling_active = False
print("\n-----[pull]-------\n")
for person ,mount in responses.items():
print(person + " Would like to climb " + mount + ".")
这篇文章从内核的角度来看ICMP的,现在,ping命令就是利用icmp实现的。
首先看一个大概。
```c
/*
*/
#include
#define MAX_WAIT_TIME 5 #define MAX_NO_PACKETS 3 #define PACKET_SIZE 4096 char sendpacket[PACKET_SIZE]; char recvpacket[PACKET_SIZE];
#1 普通文件
在写c语言的程序中,我们随手丢上了一个
至少在我的系统上(debian - 9),只要像上面没有前缀的c库头文件,默认位置存储在
/usr/include/*
上面*是为了md文件的显示好看,自己输入的时候只需要一个*.
ls /usr/include/st
stab.h stdint.h stdio.h string.h stropts.h
stdc-predef.h stdio_ext.h stdlib.h strings.h
看,有你熟悉的文件吗?
#2.有前缀的<sys/socket.h>
这个文件在编写unix网络程序的时候,是必须用到的文件之一,那么,这个文件位于哪里?记住,首先这种文件位于/usr/include/目录下。
使用命令查找一下就可以了。
find /usr/include/ -name socket.h
在我的系统上显示了如下的内容:
yubo@debian:~$ find /usr/include/ -name socket.h
/usr/include/linux/socket.h
/usr/include/asm-generic/socket.h
/usr/include/x86_64-linux-gnu/bits/socket.h
/usr/include/x86_64-linux-gnu/sys/socket.h
/usr/include/x86_64-linux-gnu/asm/socket.h
那么,从头文件上来看,上面第4个文件符合我的目的。
好了,有了以下内容,请看一下下面的头文件:
#include <stdio.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <stdlib.h>
#include <netdb.h>
#include <setjmp.h>
#include <errno.h>
其实这里面还涉及到一个glibc的问题,我们有时间再讲这方面的内容,
用法: 在变量定义之前如果使用该变量,则在使用之前加上extern
关键词,作用域从声明开始,到本文件结束。但有一点注意,还得定义一遍,只不过前面加上了关键词。
#include <stdio.h>
int mysum(int x, int y);
int main(int argc, char *argv[])
{
int result;
extern int x; /* 这里的类型名字可以去掉,但是会有警告产生 */
extern int y;
result = mysum(x, y);
printf("The max number is %d\n", result);
return 0;
}
int x = 10;
int y = 15;
int mysum(int x, int y)
{
return x + y;
}
如果整个工程由多个文件组成,在一个文件中可以引用另外一个文件中已经定义的外部变量时,则只需使用关键字extern
加以声明即可,可见,这时的变量作用域从一个文件扩展到了多个文件。
测试的例子:
a.c:
#include <stdio.h>
extern int mysum(int x, int y);
int main(int argc, char **argv)
{
int result = mysum(1, 3);
printf("Here, our result from extern mysum is %d\n", result);
}
b.c
int mysum(int x, int y);
int x = 10;
int y = 15;
int mysum(int x, int y)
{
return x + y;
}
注意编译的命令为: gcc a.c b.c -o test
还有利用这种方法去定义接口,在上面的例子中就是a.c中,再一次定义一个变量,在b.c中,使用extern
关键字来声明变量即可,然后因为你在a.c中调用的函数,所以你就可以改变传递给函数的参数了。
那么,这种方法与通过函数形参传递变量的区别在哪里?如果仅仅是传值,估计是起不到作用的,你会想到传地址的方法,这样可以,但是在一个大型项目中,可能有很多程序同时调用函数,这里就会涉及到竞态的问题。使用extern的方式就比较安全。
我一开始也有误解,现在看来,结构体的有些不同。
a.c :
#include<stdio.h>
#include "b.h"
#include "c.h" /*引入 print() */
A_class local_post = {1, 2, 3};
A_class next_post = {4,5,6};
int main(int argc, char **argv)
{
A_class ret;
print("first point", local_post);
print("second point", next_post);
ret = function(local_post, next_post);
printf("The vector is (%d %d %d)\n", ret.x, ret.y, ret.z);
printf("Or print with function(print) from c.h:\n");
print("After two array", ret);
return 0;
}
b.c
#include<stdio.h>
#include "b.h"
/* 配合b.h,*/
A_class function(A_class first, A_class next)
{
A_class ret;
ret.x = next.x - first.x;
ret.y = next.y - first.y;
ret.z = next.z - first.z;
return ret;
}
b.h:
#ifndef __B_H
#define __B_H
#if 1
typedef struct {
int x;
int y;
int z;
} A_class;
#endif
extern A_class local_post; /* 外部结构体声明*/
extern A_class function(A_class x, A_class y); /* 接口函数声明*/
#endif
c.c
#include<stdio.h>
#include "b.h"
int print(char *str, A_class post)
{
printf("%s: (%d, %d, %d)\n", str, post.x, post.y, post.z);
return 0;
}
c.h
#ifndef __C_H
#define __C_H
extern int print(char *, A_class post);
#endif
之所以还贴这么多代码,主要是觉得这个例子在内核中大量存在。除了extern关键字外,还有预定义符号,多复习。
#4 用extern声明函数 记住两点:
定义函数时,需要声明函数值返回值为extern,表示这个函数是外部函数,可以供外部文件使用。
调用函数事,也要使用extern
关键字。
代码就先不贴了。
First :
libmnl: libnftnl libmnl: git://git.netfilter.org/libmnl libnftnl: git://git.netfilter.org/libnftnl
./autogen.sh
./configure
make
make install
ldconfig
If you have error as below:
./configure: line 3960: syntax error near unexpected token `LIBMNL,'
./configure: line 3960: `PKG_CHECK_MODULES(LIBMNL, libmnl >= 1.0.0)'
please refer to here:
http://blog.anarey.info/2014/08/pkg_check_moduleslibmnl-libmnl-1-0-0-error/
这篇文章主要聚焦于debian系统,其他的linux发行版的用法应该是一致的。
You start by installing the needed tools, So, on my debian:
sudo apt-get install libvirt-dev virtinst libvirt-daemon libvirt-daemon-system
如果没有找到相应的软件包,你可以尝试一下apt-cache
命令。
(If you cant found these softwares, you can try it : apt-cache)
系统提示你缺少什么软件就安装什么软件。
sudo apt-cache search libvirt
你还可以使用通配符进行模糊查找。 (You can fuzzy search with wildcard)
Then you got a libvirtd
process running on your machine:
yubo@debian:~/git$ sudo ps u -C libvirtd
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 4470 1.4 0.7 787416 30212 ? Ssl 20:38 0:00 /usr/sbin/libvi
The role of libvirtd
is quite important. It takes care of managing the VMSrunning on your host.You can control it with command virsh
.
Before anything else, you should know that libvirt and virsh
not only allow you to control VMs running on your own system, but can control VMs running on the remote systems or a cluster of physical machines. Every time you use virsh
, With qemu,you need type it looks like:
qemu://xxx/system
qemu://xxx/session
I will introduce more details about virsh in another post,now i am focus on the libvirt-vms.
Here, libvirtd
is listening the command send to /var/run/libvirt
,so you may add a credential user for libvirt, and you have opportunity to write socket, which needs a user to belong to the libvirt
group.
If you edit /etc/libvirt/libvirtd.conf
, you can configure libvirt to wait for a commands using a variety of different mechanisms, including for example SSL encrypted TCP sockets.
yubo@debian:~/git$ sudo usermod -a -G libvirt yubo
Add my user name into libvirt group.
yubo@debian:~/git$ virsh -c qemu:///system net-list
Name State Autostart Persistent
----------------------------------------------------------
This means that there are no active virtual networks, Try one more time adding --all
:
yubo@debian:~/git$ virsh -c qemu:///system net-list --all
Name State Autostart Persistent
----------------------------------------------------------
default inactive no yes
Now your network’s is default
.
And notice the default network, If you want to inspect or change the configure file of the network, you can use either net-dumpxml
or net-edit
h -c qemu:///system net-dumpxml default
<network>
<name>default</name>
<uuid>e46e2c1b-5263-4428-b8fc-bfa4805a2ebc</uuid>
<forward mode='nat'/>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:34:36:d3'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>
</ip>
</network>
I guess you could understand what is meaning above.Now your VM bridge name is virbbr0…
You can configure networking in many different ways, with nat, with bridging,with simple gateway fowarding… You can find all parameters on the page.
And you can change the definition by using net-edit
.
net-undefine default # forever eliminate the default network
net-define file.xml #to define a new network starting from an .xml file
#you can
virsh ... net-dumpxml default > file.xml
then edit and then
virsh ... net-define file.xml
net-start default
, to start the named default
network
net-destory default
, to stop the named default
network,with the ability of starting it again in the future.
net-autostart default
, to automatically start the default network at boot.
yubo@debian:~/git$ virsh -c qemu:///system net-start default
Network default started
yubo@debian:~/git$ ps aux | grep libvirt
root 4470 0.0 0.7 1377240 30292 ? Ssl 20:38 0:00 /usr/sbi..
nobody 5155 0.0 0.0 52228 408 ? S 21:40 0:00 /usr/sb..
root 5156 0.0 0.0 52200 408 ? S 21:40 0:00 /usr/sbin/dnsmasq
----------------
yubo@debian:~/git$ sudo netstat -nulp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 192.168.122.1:53 0.0.0.0:* 5155/dnsmasq
udp 0 0 0.0.0.0:67 0.0.0.0:* 5155/dnsmasq
-----------------
yubo@debian:~/git$ sudo netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN 5155/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 546/sshd
libvirt started dnsmasq
, which is a simple dhcp server with ability to also provide DNS.So you can try:
yubo@debian:~/git$ ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
state UP group default qlen 1000
link/ether 94:c6:91:04:e6:91 brd ff:ff:ff:ff:ff:ff
inet 222.195.244.235/24 brd 222.195.244.255 scope global dynamic
enp1s0
valid_lft 2670sec preferred_lft 2670sec
inet6 fe80::96c6:91ff:fe04:e691/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
state DOWN group default qlen 1000
link/ether 52:54:00:34:36:d3 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master
virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:34:36:d3 brd ff:ff:ff:ff:ff:ff
you can use iptables to see what happened:
sudo iptables -nvL
&&
sudo iptables -t nat -nvL
Now we have a network running for our VMs,we need to worry about storage.This is similar to lvm, On this post, i just dedicated a directory to storing images and volums.
But, you should mdkir needed dir with
sudo mkdir -p /opt/kvms/pools/devel
and try it:
yubo@debian:~$ virsh -c qemu:///system \
> pool-define-as devel \
> dir --target /opt/kvms/pools/devel
Pool devel defined
Here, we create a pool called devel in a directory , we can see this pool with:
yubo@debian:~$ virsh -c qemu:///system pool-list --all
Name State Autostart
-------------------------------------------
devel inactive no
--all
as before, now we need to start it automatically with command:
yubo@debian:~$ virsh -c qemu:///system pool-autostart devel
Pool devel marked as autostarted
and start it with(must):
yubo@debian:~$ virsh -c qemu:///system pool-start devel
And you can see it again:
yubo@debian:~$ virsh -c qemu:///system pool-list --all
Name State Autostart
-------------------------------------------
devel active yes
To create and manage volumes, you can use vol-create
,vol-delete
,vol-resize
,all the vol-*
can be used.
For examole:
yubo@debian:~$ virsh -c qemu:///system vol-list devel
Name Path
------------------------------------------------------
With virt-install
yubo@debian:~$ virt-install -n debian-9 --ram 2048 --vcpus=2 \
--cpu=host -c ~/software/debian-9.1.0-amd64-xfce-CD-1.iso \
--os-type=linux --os-variant=debian \
--disk=pool=devel,size=10,format=qcow2 \
-w network=default --graphics=vnc
You must use sudo
command to execute the command,next, you will enter into linux’s installing procession.
-n
just a name.
-c
is your debian-iso where it is located. Remember here, you just define a pool named devel, however, you not have ‘create it’
--disk=pool=devel,size=10,format=qcow2
means it have 10GB space disk to support your VMs.
virt-install version 1.5.1报错debian没有在它的安装字典中,可以尝试着使用debian9.
sudo virt-install destroy domain
sudo virt-install undefine domain
This is my first wrong step to try it.I missed it.
After installing VMs, you would better to use virt-viewer
to start it.
Frist,you can start it with virsh:
virsh start my-vms #my vms-name is debian-9 or:
virsh autostart my-vms # debian-9.
So, you type virsh
into virsh’s world.
yubo@debian:~$ sudo virsh
[sudo] yubo 的密码:
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh # list
Id Name State
----------------------------------------------------
8 debian-9 running
Remember, you use it with sudo.Here, you can see your vms’s id is 8,
Again, your vm-id is 8,so next:
sudo virt-viewer --connect qemu:///system 8
Congratulations! Enjoy it:)