Skip to content

case语句的fall through

当然我说的是SHELL,不是其它的编程语言。 在看<学习KSH》中看到,把’;&’字串放在case语句中,会让case语句“fall through”(暂时没想到如何翻译,看下面的脚本输出来看看fall through是怎么回事)。实际 测试了一下发现,OpenBSD (5.8)以及DragonFly BSD (4.2)中的KSH不支持这个功能。因为他们的KSH所谓的pdksh衍生版(public domain korn shell),而Ubuntu (15.04)中通过apt-get安装的ksh是原始的Korn Shell,支持’;&’的fall through功能。 BASH shell则是从4.0版以后开始支持。 脚本:

Ubuntu:

DragonFly BSD (4.2):

   

Read more

DragonflyBSD – 配置有线网卡

在DragonflyBSD 4.2上,网卡的配置是写在/etc/rc.conf文件里面的。 比如要为某个网卡(我这里是re0)配置为使用dhcp获取ip地址,那么在rc.conf文件里写上这么一行即可: ifconfig_re0=”DHCP” 如果你不知道接口的名称,可以使用“ifconfig -a”命令查看:

上面的输出中,faith0/lo0/ppp0/sl0接口都是虚拟接口,可以忽略。 如果ifconfig -a命令没有列出你电脑上的网卡,那么很可能是DragonFlyBSD上没有网卡的驱动(尤其是一些无线网卡),或者你的网卡坏掉了/没接好。 如果要为接口配置为静态IP地址,可以这样写: ifconfig_re0=”inet 192.168.3.18 netmask 255.255.255.0″ 手工配置还需要自己配置默认网关: defaultrouter=”192.168.3.1″ 当然,还需要自己配置DNS服务器,这里略过了。 重启系统后即可生效。    

Read more

IPv6中的被请求节点组播地址

这是一个有特殊用途的组播地址,主要用于重复地址检测和获取邻居节点的链路层地址(相当于IPv4中的ARP解析)。这个组播地址的前104位是固定的,为 FF02::1:FF/104, 后24位由接口的单播地址的最后24位构成。假设某个接口的单播地址为2001:3234::1:253F,那么该接口就会自动归属于组播地址FF02::1:FF01:253F。 由于IPv6地址每16位划为一段,共8段,因此前面104位(FF02::1:FF/104)中最后的8位(也即FF)要和接口的单播地址中最后24位的前8位组合在一起形成一段。我们例子中单播地址的最后24位为01:253F(示例单播地址中倒数第二段的1其实是0001的简写),因此被请求节点组播地址为FF02::1:FF01:253F。 当此链路上其它网络接口需要给此IP发送数据时,它就会先给这个组播地址发送数据,请求它的链路层地址;而我们示例接口如果收到发往此组播地址的数据时也会进行处理和响应。同样,当某一个接口给自己配置IP地址的时候,也会使用这个组播地址来进行重复地址检测;也就是说如果这个新分配的IP地址的最后24位是01:253F,那么它也会发送数据报到这个组播地址,看看是否已经有其它接口配置了相同的IP地址,如果没有收到应答,则表示没有重复地址;如果收到应答,则会比对应答数据包的源地址来判断是否重复。

Read more

unix文件中的ctime, mtime和atime

今天需要使用find命令来查找一些文件,需要找到15天前创建的文件。究竟该用哪个参数呢,ctime,mtime还是atime? 那就再来复习一下这三个参数具体的意义吧。 不过,在谈论这三个参数之前,你得先了解inode(索引节点)的概念,不然是说不清的。inode是干嘛用的?它是用来存储文件属性的一个数据结构,比如文件的权限,所有者,大小,指向本文件的连接数等,当然也包括文件的更新时间等信息(但不包含文件名以及文件的内容)。在表现形式上,inode是一个数字,每个文件都对应一个唯一的inode。可以使用ls命令的‘-i’参数来查看文件或目录的inode:

当新建一个文件时,系统会自动分配一个inode号码。 更具体的inode信息,大家可以网上搜索一下。今天不再详细介绍。 ok,有了这些背景信息,我们可以介绍这三个参数了。 ctime ctime是文件属性更新的时间。比如更新了文件的所有人,更改了文件的读/写/执行权限等。也可以理解为,任何对inode数据结构里的信息进行的更新都会引起ctime的更新(但下面atime的测试说明这个说法需要进一步考证) mtime 文件内容更新的时间。 这个是最直观的。你打开文件,编辑了其中的内容,在你保存时,系统会更新文件的mtime属性。 要注意的是,更新mtime时,通常也会需要更新ctime;有时候更新ctime却未必需要更新mtime(比如为文件添加可执行权限)。   atime 文件最后访问时间。 每次打开一个文件时,或者使用grep/sort等命令访问文件时系统也会更新文件的atime。 那么系统更新文件的atime,意味着文件的属性发生了改变,应该同时更新ctime。但下面的测试表明不是这样的。

上面的测试说明,使用grep命令访问了文件以后,atime(Access)更新了,但ctime(Change)并没有更新。不解中 …… 同时,如果以root账户测试,grep/cat/sort等命令不更新atime。 同时查看了一下文件系统的挂载选项,发现有一个‘relatime’的选项(如果使用了noatime选项挂载,系统就不会更新文件的atime):

mount手册这样解释relatime选项(我第一次知道这个选项,BSD类系统上没有这个):        relatime Update inode access times relative to modify or change time.  Access time is…

Read more

IPv6地址的自动配置

考虑到移动网络的出现以及以后的物联网,IPv6中对IP地址的配置做了许多改进,以适应漫游节点越来越多的情况。 其中一个特性就是IPv6地址的自动配置功能,它可以在网络没有DHCP服务器的情况下自行为接入的节点配置IPv6地址,从而让节点可以与网络中的其它节点(也可能包括互联网上的其它节点)进行通讯。 IPv6的地址自动配置分为两种情况: 无状态自动配置(网络中有路由器,但无DHCPv6服务器),有状态自动配置(有DHCPv6服务器,可能有路由器)。 有人可能会想,如果一个网络中既没有路由器,也没有DHCPv6服务器,那是什么情况?这种情况就相当于几台电脑接入到一个交换机或者集线器上,这时各个节点只需要一个链路本地地址就可以互相通讯。而链路本地地址的配置无需任何网络,一个支持IPv6的节点自己就可以完成链路本地地址的配置了。所以这里我们说的IPv6地址的自动配置,说的是全球单播地址(相当于IPv4公网IP)的配置。 当一个支持IPv6的节点启动时,它首先会尝试为自己配置一个链路本地地址(link-local address),这个地址是根据链路本地地址的网络前缀FE80::/64以及接口的MAC地址来生成的,既不需要路由器也不需要DHCPv6服务器。有了这个地址以后,节点会以组播方式发送RS(Router Solicitation )报文,看看本地有没有路由器(有没有设备应答RS报文)。此时链路上的路由器会以RA(Router Advertisement)报文应答,应答报文中携带了网络前缀等相关信息,节点通过这些信息来配置自己的全球单播地址。注意,在无状态自动配置中无法为节点配置DNS服务器等一些选项。 如果节点没有收到路由器的RA报文,或者路由器RA报文中通知节点此网络中有DHCPv6服务器,则节点发送相应报文来请求DHCPv6服务器发送网络前缀等相关的网络配置信息。这种方式称为有状态自动配置。 大家也可以参考这个(英文的)PDF文件: https://www.6diss.org/tutorials/autoconfiguration.pdf

Read more

特殊IPv6地址

就像IPv4一样,IPv6也有一些特殊的地址。见下表: IPv4 地址 IPv6 地址 互联网地址类 (Internet address classes) 不适用于 IPv6 组播地址 (Multicast addresses 224.0.0.0/4) IPv6 组播地址 (multicast addresses (FF00::/8)) 广播地址(Broadcast addresses) 不适用于 IPv6 未指定地址 (Unspecified address is 0.0.0.0) 未指定地址  :: 环回接口地址 (Loopback address is 127.0.0.1) 环回接口地址 ::1 公网IP地址 (Public…

Read more

IPv6中的常见地址类型

IPv6中的地址类型相对与IPv4有一些明显的变化。IPv4中有三种类型: 单播地址、组播地址和广播地址。而IPv6中则是单播地址、组播地址和任播地址(Anycast)。IPv6中取消了广播地址(因为v6地址多,子网一般可包含更多的节点,这个时候用广播方式发送数据很容易形成网络风暴),而增加了任播地址。 先上图,看起来更直观一些: (via http://1.bp.blogspot.com/-D86FInU1mdY/UjqoFkWarBI/AAAAAAAAATY/9hPoD99J1UM/s1600/Untitled.png) 单播地址 顾名思义,单播地址就是用于标识网络中某一个特定接口的地址,对应于IPv4中的IP地址。 同样,就像IPv4中的地址又分为公网地址、私有地址(如192.168.0.0/16 …)等不同子类一样,IPv6的单播地址也分为很多种,比IPv4的种类更多 。下面简单的一一介绍一下。 1. 全球唯一单播地址 对应IPv4中的公网地址,以2000::/3开头 2. 站点唯一单播地址 对应于IPv4中的私有地址,以FEC:: ~ FFF::开头,用于标识本地站点上一个唯一的接口(可以想象为一个公司的局域网) 3. 链路唯一单播地址 对应于IPv4中的私有地址网段,以FE8:: ~ FEB::开头,用于标识本地链路上一个唯一的接口(可以想象为接入一个交换机上的接口) 组播地址 这个类型和IPv4中的组播地址功能一样,用于定义一组接口,发往组播地址的数据会被转发到组中的每个接口上 任播地址 任播地址也是用于标识一组接口地址。发往任播地址的数据会被转发给组中距离接收接口最近的一个地址(而不是组中所有的地址)。 当然,IPv6中还有用于标识本机的环回接口地址(::1,对应于IPv4的127.0.0.1),被保留的地址段,一起其他一些特殊地址(比如::,对应IPv4中的0.0.0.0),但主要用的就是上面三种地址类型。  

Read more

GETOPTS中的OPTIND

最近对shell中的OPTIND变量有些糊涂,想要查看文档弄清楚。可惜无论KSH还是BASH的手册中对这个变量都只是提了一下定义:OPTIND是一个索引,用于指向调用getopts函数时需要处理的参数,它的初始值为1。并没有展开论述,也没有范例。 如果只看这个定义的话,倒也很清楚。不过实际一测试,反而容易糊涂,尤其是碰到需要值(argument)的参数。请看下面一个简单的示例脚本: 在Linuxmint/ubuntu上:

这里我们的脚本可以处理3个参数,a, b和c,其中c参数需要跟一个值。实际运行结果如下:

调用getopts之前,OPTIND的值为初始值1,getopts被调用后返回第一个参数a,同时OPTIND变为2,因此第二次调用getopts时返回第二个参数b,同时OPTIND变为3。同理,第三次调用getopts时返回第三个参数c,同时OPTIND变为5,因为值xd也同样算一个数的。第四次调用getopts时,由于不存在第五个参数,getopts返回-1,while循环结束。 看起来很清楚,没什么好糊涂的。 下面我们再看一下把参数合并后脚本运行的结果:

这个时候由于abc混在一块,从形式看都是第一个参数,因此OPTIND一直为1也可以理解。但是不知道shell的内部是如何区分这几个参数的呢? 但在OpenBSD上(估计其他BSD也一样),结果就有点差别了(参数分开的情况下结果是相同的):

但合并的时候就不同了:

不知为何。

Read more
Sidebar