사용자로부터 입력(소스 경로)을 받아 도커 컨테이너 내부의 볼륨에 연결하는 다음 스크립트가 있습니다.
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