我想做一组实验,其中每个实验都被描述为一个docker-compose。结构如下:
Dataset
A
1
docker-compose-1.yml
docker-compose-2.yml
2
docker-compose-1.yml
...
B
1
docker-compose-1.yml
...
所有的组合都表现得很好,也就是说我可以手动运行它们,它们的行为与预期一致。
我尝试了两次,第一次是一个shell文件,如下所示:
#!/bin/bash
target_dir=../dataset
localizedCompose() {
f=$1;
ff=`basename ${f}`
d=`dirname ${f}`
l=`pwd`
cd $d
echo "Docker-Composing ${d}/${ff}"
docker-compose -f $ff up
echo "Docker-Compose finished ${d}/${ff}"
docker-compose -f $ff down
echo "Docker-Compose cleaned-up"
cd $l
}
export -f localizedCompose;
find $target_dir -name 'docker-compose*.yaml' -print0 | sort -zn | xargs -I {} bash -c 'localizedCompose "$@"' _ {}
| sort -zn是按顺序运行文件,这不是非常重要,但会很好。
在第一个组合之后结束。同样地,我试着用find来运行它。如
find ./dataset -type f -name docker-compose*.yml -exec bash -c "docker-compose -f {$1} up ; docker-compose -f {$1} down" {} ;
这个(令人惊讶的)也运行它找到正确的第一个组合,但之后也退出。
由于实验资源昂贵,需要定时,它们真的必须互相配合,我不能把它们合并成一个大的组合。
您没有将-0
参数传递给xargs
。否则,它将其stdin解释为空格分隔的字符串序列;因为没有空格,所以它只运行一次命令;但是C程序的一个典型约定是将空字节解释为字符串的结束,所以实际上你只会得到第一个文件名。
find ... -print0 | xargs -0 ...
在实践中,我会尝试简化这一点,可能使用for
循环
for f in $(find "$target_dir" -name 'docker-compose*.yaml' -print | sort -n)
do
localizedCompose "$f"
done
如果任何文件或目录名中有空格,这可能会遇到一些问题。如果您可以使用特定于bash的语法,您应该能够避免这个问题:
shopt -o failglob globstar
for f in **/docker-compose*.yaml; do # automatically sorted
localizedCompose "$f"
done
在函数中,Compose通常忽略工作目录,并考虑与(第一个)-f
选项的位置相关的所有路径。您可以将此函数精简为
localizedCompose() {
echo "docker-compose up $1"
docker-compose -f "$1" up
echo "docker-compose down $1"
docker-compose -f "$1" down
echo "done with $1"
}