2017-06-01 69 views
2

我有一个接受作为参数的脚本;那么我的脚本必须根据这个参数创建一个具有多个端口映射的docker容器;例如,如果我跑。 /myscript.sh 10,myscript.sh必须创建一个具有10个端口映射的Docker容器。取决于脚本参数的Bash多端口映射

这是我的myscript.sh

#!/bin/bash 

NCACHES=$1 
PORT_BASE=80 

docker run -idt --name CONTAINER then..? 

如果参数值,例如,如图5所示,我愿意的MyScript创建具有端口映射80,81,82,83,84的容器。我怎么能在bash脚本中管理这个条件?

参数值= 5时,预计会有:docker run -idt --name MYNAME -p 80:80 -p 81:81 -p 82:82 -p 83:83 -p 84:84

编辑:我已经尽我的脚本:

#!/bin/bash 

echo $1 

docker run -idt --name CONTAINER `for x in {80..$((80 + ${1}))}; do printf "-p ${x}:${x} "; done` pier92/balancer:latest 

但这是输出:

./mapping.sh 5 
5 
./mapping.sh: riga 9: printf: -p: opzione non valida 
printf: uso: printf [-v var] formato [argomenti] 
75899b1ec4edab51530ad8c33e955a31a45fb946ecc6eb2fa3f1ba5b5537064a 
[email protected]:~/Scrivania/setup-arch/webapp$ docker ps 
CONTAINER ID  IMAGE      COMMAND     CREATED    STATUS    PORTS                         NAMES 
75899b1ec4ed  pier92/balancer:latest  "nginx -g 'daemon ..." 7 seconds ago  Up 4 seconds  80/tcp, 443/tcp                      CONTAINER 

只有映射端口80。

+0

你如何将这些端口映射传递给'docker'? – Inian

+0

与参数值= 5,它应该有:码头运行-idt - 名称MYNAME -p 80:80 -p 81:81 -p 82:82 -p 83:83 -p 84:84 – pier92

+1

我认为是什么你现在问的是很容易改变一下代码,你应该自己尝试一下,这样你会学到更多! – criw

回答

2

我宁愿使用一个数组,并通过操纵里面的内容,

portArr=() 
for ((i=0;i<NCACHES;i++)); do 
    portArr+=(-p "$((PORT_BASE+i)):$((PORT_BASE+i))") 
done 

一旦该阵列被填充,就可以通过印刷

declare -p portArr 

验证其内容显示每索引值,

declare -a portArr='([0]="-p" [1]="80:80" [2]="-p" [3]="81:81" [4]="-p" [5]="82:82" [6]="-p" [7]="83:83" [8]="-p" [9]="84:84")' 

现在将它传递给docker命令为

docker run -idt --name MYNAME "${portArr[@]}" 
+1

'-p'和这对端口需要是数组的单独元素。 'portArr + =(-p“$((PORT_BASE + i)):$((PORT_BASE + i))”)' – chepner

+0

@chepner:谢谢!已经利用你的建议! – Inian

+0

@Inian我编辑了我的问题,做同样的事情,但在主机模式中的泊坞窗群。 – pier92

1

什么是这样的:

docker run -idt --name CONTAINER `for x in {80..$((80 + ${1}))}; do printf "$x "; done` 

输出会是这样的:

docker run -idt --name CONTAINER 80 81 82 83 84 85 86 87 88 89 90 

释:

这只是针对打印数字的序列内联。

要在bash中进行总和等操作,请使用此语法$((x + y))


编辑:

只需在您需要显示的printf一切增加,在这种情况下将是:

docker run -idt --name CONTAINER `for x in $(seq 80 $((80 + ${1}))); do printf " -p ${x}:${x}"; done` 

其输出例如:

docker run -idt --name CONTAINER -p 80:80 -p 81:81 -p 82:82 -p 83:83 -p 84:84 -p 85:85 -p 86:86 -p 87:87 -p 88:88 -p 89:89 -p 90:90 

正如Brian Agnew所指出的那样,你ha有变量使用$(seq x y),谢谢!

+0

我编辑了我的问题。对于每个端口都有一个“-p”标志。看我的例子。 – pier92

+0

你有,也许有更好的方法来做到这一点,但应该工作 – criw

+2

范围内的变量扩展实际上是否工作?它并不像我期望的那样在命令行上展开 –

2

你可以通过这样的顺序循环:

for i in $(seq 1 $1); do 
    echo $i; 
done 

这将1和你输入数值参数之间循环。你可以在上面添加一个代表你的命令行的字符串。

请注意,您可以使用${1..5}(比如说)在固定值之间扩展bash中的范围,但在范围内使用变量时这不起作用。

+0

不要使用'seq';它不是POSIX标准的一部分,所以在'bash'中你也可以((i = 1; i <= $ 1; i ++)); do';如果你需要POSIX兼容性,使用'i = 1; while [“$ i”-le “$ 1”]; do ...; i = $((i + 1)); done' – chepner

+0

我重视POSIX,但我承认这是我很少担心并且从未被咬过的东西。例如,我刚刚调查了我的开发环境和prod服务器,并且都有/ usr/bin/seq。我很想看看有多少人受到这种情况的影响 –

+0

我认为这里的答案应该力求成为“过度”是正确的,因为你不知道谁可能会尝试使用答案。从更实际的角度来看,为什么如果你不需要在内存中生成一个(可能很长的)数字列表? – chepner