存档在 2011年10月

shell中的环境变量和自定义变量

2011年10月6日

Shell中的变量可以简单分为环境变量和自定义变量。环境变量有时也被称为全局变量,它是操作系统为Shell事先定义的一组变量,这些变量共同描述了当前Shell运行的系统环境;而自定义变量则是用户根据所需而定义的变量,它也被称为局部变量。为了区分两者的不同,环境变量通常用大写字母表示,而自定义变量通常使用小写子母表示。

1.环境变量

环境变量是一组变量的集合,它们描述了当前Shell运行的环境信息。最典型的环境变量即为PATH,它描述了可执行文件的路径信息。通过env命令可以查看当前Shell环境下所有环境变量及其内容。

edsionte@edsionte-desktop:~$ env
TERM=xterm
SHELL=/bin/bash
USER=edsionte
USERNAME=edsionte
PATH=/home/edsionte/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/edsionte/bin
PWD=/home/edsionte

…………

下面对部分环境变量做以解释:

HOME:表示当前用户的主目录。当输入cd或cd ~命令时,就会用到这个变量,如果更改了这个变量的值,那么使用上述命令的结果也会相应的改变。

SHELL:表示当前的shell环境所使用的shell程序。常见的shell程序有/bin/bash和/bin/sh,Linux中默认使用的是/bin/bash。

PWD:shell当前所在的工作目录,这个变量的值是通过pwd命令得到的。

USER:当前的用户名。

2.自定义变量

Shell除了环境变量,还包括用户自定义的变量。env命令查看的只是所有环境变量,而set命令既可以查看环境变量也可以查看自定义变量。比如:

edsionte@edsionte-desktop:~$ myvar=test
edsionte@edsionte-desktop:~$ env | grep myvar
edsionte@edsionte-desktop:~$ set | grep myvar
myvar=test

3.环境变量和自定义变量之间的转换

环境变量有在Linux下的shell程序默认为Bash,因此每一个Bash其实都是一个进程,在当前Bash下输入ps命令则可以查看该Bash的PID。对于环境变量而言,每个Bash进程都可以对其进行引用;而对于用户自定义的变量,只有对其定义的Bash进程可以引用它,其他的Bash进程甚至是其子进程均不可以引用。这也是环境变量和自定义变量的的主要区别之一。

从进程内存映像的结构分布可以很好的解释环境变量和自定义变量之间的差异。在Linux系统中,所有的Bash进程都是gnome-terminal进程的孩子或孙子,而gnome-terminal进程是由init进程创建的,由于环境变量保存在gnome-terminal进程的数据段,因此它的孩子或孙子(即Bash进程的孩子)均可以继承数据段的数据,即所有Bash进程都可以访问环境变量。对于自定义变量而言,它位于每个Bash进程的栈中,而每个进程它都有自己独立的段,因此自定义变量是不能被继承的,即自定义变量不能被其他bash进程引用。

那么,环境变量和自定义变量之间如何相互转换呢?通过export命令和declare命令即可完成。如果要将一个自定义变量转化为环境变量,则需要使用下述命令:

edsionte@edsionte-desktop:~$ myvar=test
edsionte@edsionte-desktop:~$ env | grep myvar
edsionte@edsionte-desktop:~$ export myvar
edsionte@edsionte-desktop:~$ env | grep myvar
myvar=test

如果要将环境变量转化为自定义变量,则需使用下述命令:

edsionte@edsionte-desktop:~$ declare +x myvar
edsionte@edsionte-desktop:~$ env | grep myvar
edsionte@edsionte-desktop:~$ echo $myvar
test

关于exprot和declare命令更多的用法,可以参考man手册。

inotify机制在内核态下的使用方法

2011年10月5日

inotify是一种使用简单而功能强大的文件系统事件监控机制。在用户态下通过一组简单的系统调用即可使用inotify机制监控文件的变化,而在内核态中也可以通过一组API来inotify机制。

1.创建并初始化inotify实例

为了在内核中使用inotify机制,必须首先创建并初始化一个inotify实例,每个inotify实例其实对应的是一个数据结构inotify_handle。

struct inotify_handle {
	struct idr		idr;		/* idr mapping wd -> watch */
	struct mutex		mutex;		/* protects this bad boy */
	struct list_head	watches;	/* list of watches */
	atomic_t		count;		/* reference count */
	u32			last_wd;	/* the last wd allocated */
	const struct inotify_operations *in_ops; /* inotify caller operations */
};

创建并初始化一个inotify实例的过程其实就是分配并初始化一个inotify_handle结构,这个过程通过inotify_init()完成。此外,每个inotify实例都与一个inotify_operations结构相关联,该结构中有两个钩子函数,分别定义了事件处理和销毁watch两个函数的接口,这两个钩子函数应该根据具体的应用场景来实现。

struct inotify_operations {
	void (*handle_event)(struct inotify_watch *, u32, u32, u32,
			     const char *, struct inode *);
	void (*destroy_watch)(struct inotify_watch *);
};

一个inotify_init()通用的使用方法如下:

struct inotify_operations *ops;
ops->handle_event = my_handle_event;
ops->destroy_watch = my_destroy_watch;
struct inotify_handle *ih = inotify_init(ops);

也就是说,通过向inotify_init()中传入一个inotify_operations结构的变量来实现钩子函数和inotify实例之间的关联。

2.添加watch

从inotify实例所对应的数据结构inotify_handle中可以看出,每个inotify实例都拥有一个由watch组成的链表。该双链表上的每个watch即代表该inotify实例所监控的对象,这个对象可能是文件,也可能是目录。每个watch在内核中的表示如下:

struct inotify_watch {
	struct list_head	h_list;	/* entry in inotify_handle's list */
	struct list_head	i_list;	/* entry in inode's list */
	atomic_t		count;	/* reference count */
	struct inotify_handle	*ih;	/* associated inotify handle */
	struct inode		*inode;	/* associated inode */
	__s32			wd;	/* watch descriptor */
	__u32			mask;	/* event mask for this watch */
};

该结构中每个字段的含义如下:

h_list:一个inotify实例中所有watch组成一个双链表,h_list表示当前watch在该双链表中所处的结点。该双链表的表头即为inotify_handle结构中的watches字段。

i_list:一个文件可能被多个inotify实例监控,而被监控一次就产生一个watch,该文件对应的所有watch组成一个双链表,i_list表示当前watch在该双链表中所处的结点。该双链表的表头即为inode结构中的inotify_watches字段。

count:表示该watch被引用的次数。

ih:每个watch必然属于某个inotify实例,该字段指向当前watch所属的inotify_handle结构。

inode:该字段指向当前watch所关联的文件的inode。

wd:表示当前watch的文件描述符。

mask:表示当前监控对象所对应的事件掩码。

当初始化完一个inotify实例后,通过inotify_add_watch()即可向该实例中添加watch。不过在添加前还需通过inotify_init_watch()对每个watch进行初始化。

对watch初始化完成的主要工作即初始化两个链表结点、该watch的引用计数等。向inotify实例添加一个watch主要完成的工作即为向两个watch链表中添加当前的watch结点,并且更新watch的引用计数等。

3.删除一个watch

从指定的inotify实例中删除一个watch所完成的工作其实和添加watch的过程相反,通过inotify_rm_watch()即可完成。

4.对监控事件的处理

handle_event()通常并不对具体的监控对象做处理,而是作为所有监控事件的入口点;接着根据每个事件的掩码做出“分流”动作,即对具体的监控事件做以处理。

windows 7 ultimate product key

windows 7 ultimate product key

winrar download free

winrar download free

winzip registration code

winzip registration code

winzip free download

winzip free download

winzip activation code

winzip activation code

windows 7 key generator

windows 7 key generator

winzip freeware

winzip freeware

winzip free download full version

winzip free download full version

free winrar download

free winrar download

free winrar

free winrar

windows 7 crack

windows 7 crack

windows xp product key

windows xp product key

windows 7 activation crack

windows7 activation crack

free winzip

free winzip

winrar free download

winrar free download

winrar free

winrar free

download winrar free

download winrar free

windows 7 product key

windows 7 product key