В 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...
Закомментируйте или удалите строку deb cdrom:
в верхней части /etc/apt/sources.list
, чтобы избавиться от сообщения об ошибке, и удалите все повторяющиеся записи в /etc/apt/sources.list.d/wine.list
, чтобы избавиться от предупреждающих сообщений.