2017-06-01 66 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