ユーザーから入力(ソースパス)を受け取り、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
これらの変数の数はユーザー入力によって異なります。
答え1
では、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
)格納されるため、docker
シェルと上記のコードがパス名で受け入れられない唯一の文字は、読み取る行を区別するためですread
。
上記のスクリプトは、入力行ごとに単一のパスを含むテキストファイルのリダイレクトされた入力も許可します。
引用が重要であることに注意してください。変数拡張の周りに二重引用符がない場合、スペースを含むパスは使用できず、シェル特殊文字を含むパスに問題が発生する可能性があります。
関連:
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 ...
答え2
これを試してみてください。ディレクトリ名にスペースを含めることはできません。
#!/bin/bash
echo -n "Enter the Directories, space separated : "
read dirs
docker run $( set -- $dirs; for path; do echo -v $path:/opt/$path/; done ) fedora
このように入力するfoo bar
と実行されます。
docker run -v foo:/opt/foo/ -v bar:/opt/bar/ fedora
答え3
#!/bin/bash
echo -n "Enter the Path : "
read path
echo -n "docker run "
echo "${path}" | tr " " "\n" | while read value
do
echo -n "-v ${value}:/opt/${value} "
done