shell中的動態變數
我有一個以下腳本,它將從使用者那裡獲取輸入(源路徑),並將在 docker 容器中附加卷
echo -n "Enter the source path: " read path docker run -v $path:/opt/$path/ fedora
問題是,我想創建一個循環,以便使用者可以提供多個源路徑,並且可以附加到 docker 容器。
例如
docker run -v $path1:/opt/$path1 -v $path2:/opt/$path2
等等,這些
$path
變數的數量取決於使用者輸入。
在
bash
中,您應該使用一個數組來保存從使用者那裡讀取的路徑。通常,最好將單獨的字元串(路徑名)分開,而不是將它們連接成一個字元串,以後必須正確解析以提取原始組成字元串。#!/bin/bash echo 'Enter paths, one by one followed by Enter. End input with Ctrl+D' >&2 mypaths=() while IFS= read -r -p 'Path: ' thepath; do mypaths+=( -v "$thepath:/opt/$thepath" ) done docker run "${mypaths[@]}" fedora
在這裡,提示使用者多次輸入路徑,直到他們按下
Ctrl+D
。輸入的路徑保存在mypaths
數組中,該數組的佈局方式docker
可以直接使用它。一旦沒有更多要讀取的路徑,
docker
就會呼叫該命令。將"${mypaths[@]}"
擴展為mypaths
數組中單獨引用的元素。由於數組的條目按原樣儲存(-v
在每個特殊格式化的字元串之前作為單獨的元素pathname:/opt/pathname
),因此 shell 和docker
. 上述程式碼在路徑名中唯一不能容忍的字元是換行符,因為這些字元將read
.上面的腳本還將接受從包含每行輸入的單個路徑的文本文件重定向的輸入。
請注意,引用很重要。如果沒有圍繞變數擴展的雙引號,您將無法使用包含空格的路徑,並且您可能還會遇到包含 shell 特殊字元的路徑的問題。
有關的:
對於非
bash
(sh
) 殼:#!/bin/sh echo 'Enter paths, one by one followed by Enter. End input with Ctrl+D' >&2 set -- while printf 'Path: ' >&2 && IFS= read -r thepath; do set -- "$@" -v "$thepath:/opt/$thepath" done docker run "$@" fedora
在這裡,我們使用位置參數列表而不是數組(因為數組以外的數組
$@
通常不可用sh
),但是除了使用printf
.在 Stéphane Chazelas 的評論末尾實施建議,以便腳本在其命令行上獲取路徑名,而不是從其標準輸入中讀取它們。這允許使用者將任意路徑名傳遞給腳本,即使是那些
read
無法輕鬆閱讀或使用者無法輕鬆在鍵盤上鍵入的路徑名。對於
bash
使用數組:#!/bin/bash for pathname do mypaths+=( -v "$pathname:/opt/$pathname" ) done docker run "${mypaths[@]}" fedora
對於
sh
使用位置參數列表:#!/bin/sh for pathname do shift set -- "$@" -v "$pathname:/opt/$pathname" done docker run "$@" fedora
這兩個都將像
./script.sh path1 path2 path3 ...