考虑 roles 的定义,其中每一行都是空的,注释(以哈希符号为前缀)或角色定义。角色定义由名称后跟冒号和无,一个或多个空格分隔的角色依赖项组成:
# this is a comment
somerole: role2 role3
role2: role3
# 'empty' roles should be supported as well
roled:
anotherrole: somerole role2
我想以一种我可以迭代它们的方式在bash函数中获取所有依赖角色。它们只需要按正确的顺序列出一次,例如如果role1依赖于role2,而role2依赖于role3,则顺序必须是 role3,role2,role1 ,而不是 role1,role2,role3 。保证定义文件不包含任何循环依赖。
我可以通过遍历每个条目来解析角色文件(非常天真,确实如此),如
for role in $(cat "$ROLEFILE" |grep -v -e '^$' -e '#'); do
# test if name ends with colon
echo $role|grep -qe ':$'
if [ $? -eq 0 ]; then
# remove last character
role=$(echo $role|sed 's/.$//')
echo "new role definition: $role"
else
echo "role depenency: $role"
fi
done
但是,我如何构建唯一的依赖关系集,并收集给定输入角色的依赖关系?
这是一个示例调用的样子。每个依赖项都需要在依赖于它的角色之前打印。最终的角色始终是我们要求的角色。
$ ./testroles somerole
role3 role2 somerole
$ ./testroles roled
roled
$ ./testroles anotherrole
role3 role2 somerole anotherrole
生成的脚本应该与Ubuntu 14.04和OS X一起使用。
答案 0 :(得分:1)
为什么不逐行解析文件?
while read line; do
dep=$(echo $line | cut -d ":" -f2)
role=$(echo $line | cut -d ":" -f1)
echo "$dep $role"
# or do anything you want...
done < $ROLEFILE
答案 1 :(得分:1)
我创建了下面的脚本,它就像你描述的那样打印依赖树。它使用shell_map来创建角色依赖关系的映射。
#!/bin/bash
source shell_map.sh
ROLE_ARG="$1"
ROLEFILE=input.sh
# create a new map where roles are keys and deps are values
shell_map new roles_map
while read line; do
#skip comments
[[ $line =~ ^#.*$ ]] && continue;
#skip blank lines
[[ "$line" =~ ^[[:alpha:]]+ ]] || continue;
deps=$(echo $line | cut -d ":" -f2)
role=$(echo $line | cut -d ":" -f1)
# put in the map
roles_map put $role "$deps"
done < $ROLEFILE
# this map will store the dependency tree without repetitions
shell_map new deps_tree
function role_deps {
local role=$1
local my_deps=`roles_map get $role`
[ -z "$my_deps" ] && return 0
for dep in $my_deps; do
deps_tree put $dep ""
for inherited_dep in `role_deps $dep`; do
deps_tree put $inherited_dep ""
done;
done
# echoes the dependencies stored in the map
deps_tree keys
}
echo `role_deps $ROLE_ARG` $ROLE_ARG