shell命令的执行顺序问题·拓扑排序的扩展

shell命令操作文件时有些特殊的顺序问题:

比如:

1. 管理员修改用户的问题:

useroldnew
u1200300
u2300

400

u1用户要从原先的uid:200改为uid:300,要将文件系统内所有属于200的文件全部改为300

u1改为300后与u2用户相同,就造成冲突,u2却要从300改为400

对于这个问题首先想到的是先改变u2的用户ID,这样文件系统内就不存在300这个ID的文件,然后再改u1用户的,命令较少的情况下可以人为的控制命令的执行顺序,命令很多时,就不行了

这个问题所反映出来的是,资源的关系问题,文件系统是个公共资源,被很多用户共同拥有,多用户的操作必然会存在竞争,这种冲突就是因为目标资源已经存在造成的。

像这种从源到目标的操作,必须要先确定目标是否会作为另一个操作的源,如果是,则必须先执行那个操作。

将从源到目标的一次操作定义为op,多个op之间的执行顺序需要排定,以保证op之间不会冲突:

一个op的目标,是否会作为op1的源,就确定了op1要先于op执行,这样就确定了一个局部的op1和op的顺序

将所有的op都按照这个规则确定相互之间的顺序,就得到了很多个局部的op和op之间的顺序,这样由局部的顺序问题推理出全局的顺序问题就是拓扑排序。

我们再分析,op的顺序中却蕴含着另外一种顺序,就是目标到源的顺序,目标作为另一个op的源的先执行,也就是目标先于源。

因此我们现将 目标->源 这样的局部顺序先进行拓扑排序。

这个操作是简单的,直接将每个op里面的new和old取出来送入拓扑排序器:tsort命令。

duanyongchao@zhaoyuke-Android:~$ tsort <<EOF
> 300 200
> 400 300
> EOF
400
300
200

排序后的输出就是一串ID顺序,但还不是op的顺序,此时需要将ID顺序编号,第一个编号0,第二个为1,依次类推。

这个ID编号顺序就反映着op的顺序,u1  200  300 这个op中200的编号和300的编号会大于u2  300  400这个op中300的编号和400的编号,因此,u1  200  300 这个op赋值为300对应的ID编号1,u2  300  400 这个op对应的ID编号0,这样每个op有一个编号,将op的编号从小到大排序就是op的执行顺序。

使用shell脚本很容易将这个算法实现:

#! /bin/bash

OPFILE="op.txt"  #存放命令以空格分隔字段:u1 200 300
SEEPIPE='tee >(while read line ;do echo $line >&2 ;done ;echo "------" >&2 )' #管道数据查看器
awk '
	BEGIN{
		file = ARGV[1]
		delete ARGV[1]
		while(getline < file)
		{
			uid[$0] = i++
		}
	}
	{
		print uid[$3] ":" $0
	}
' <(awk '{print $3,$2}' $OPFILE | eval $SEEPIPE | tsort | eval $SEEPIPE)  "$OPFILE"  |
	eval $SEEPIPE | 
	sort -t: -k1n |
		eval $SEEPIPE |
		awk -F: '{print $2}'


此命令的执行结果如下:

duanyongchao@zhaoyuke-Android:~$ cat op.txt
u1 200 300
u2 300 400
u3 500 700
u4 400 500
u5 800 900
duanyongchao@zhaoyuke-Android:~$ ./topsort
300 200
400 300
700 500
500 400
900 800
------
700
900
500
800
400
300
200
------
5:u1 200 300
4:u2 300 400
0:u3 500 700
2:u4 400 500
1:u5 800 900
------
0:u3 500 700
1:u5 800 900
2:u4 400 500
4:u2 300 400
5:u1 200 300
------
u3 500 700
u5 800 900
u4 400 500
u2 300 400
u1 200 300

最终命令的执行顺序为 u3->u5->u4->u2->u1,完全符合操作顺序

2.搬家具的问题:

要将一个家具挪动到另一个位置,必须先确定另一个位置是否有家具

3.拼图的问题

要移动一格,必须保证移动到的格子是空的

等等,还有很多关于资源占有的导致的op顺序的排定问题


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值