Em bash , você deve usar uma matriz para manter os caminhos como lidos pelo usuário. Em geral, é melhor manter strings separadas (nomes de caminho) separadas, em vez de concatená-las em uma única string que depois você precisa analisar corretamente para extrair as strings constituintes originais.
#!/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
Aqui, o usuário é solicitado a inserir um caminho várias vezes até que pressione Ctrl + D . Os caminhos inseridos são salvos no array mypaths , que é apresentado de tal forma que docker pode usá-lo diretamente.
Quando não houver mais caminhos para ler, o comando docker será chamado. O "${mypaths[@]}" será expandido para os elementos citados individualmente da matriz mypaths . Como as entradas da matriz são armazenadas da maneira como estão (com -v como um elemento separado antes de cada string pathname:/opt/pathname formatada especialmente), isso será interpretado corretamente pelo shell e por docker . Os únicos caracteres que não serão tolerados nos nomes de caminho pelo código acima são as novas linhas, pois estão separando as linhas lidas por read .
O script acima também aceitaria entrada redirecionada de um arquivo de texto contendo um único caminho por linha de entrada.
Observe que a cotação é importante. Sem as aspas duplas em torno das expansões de variáveis, você não seria capaz de usar caminhos contendo espaços em branco, e você também teria problemas com caminhos contendo caracteres especiais para o shell.
Relacionados:
Para não- bash ( sh ) shells:
#!/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
Aqui, usamos a lista de parâmetros posicionais em vez de uma matriz (já que matrizes diferentes de $@ não estão disponíveis em sh em geral), mas o fluxo de trabalho é idêntico, além de imprimir o prompt explicitamente com printf .
Implementando a sugestão no final do comentário de Stéphane Chazelas , para que o script tenha nomes de caminho em sua linha de comando, em vez de lê-los a partir de sua entrada padrão. Isso permite que o usuário passe nomes de caminhos arbitrários para o script, mesmo aqueles que read não conseguem ler facilmente ou que um usuário não consegue digitar facilmente em um teclado.
Para bash usando uma matriz:
#!/bin/bash
for pathname do
mypaths+=( -v "$pathname:/opt/$pathname" )
done
docker run "${mypaths[@]}" fedora
Para sh usando a lista de parâmetros posicionais:
#!/bin/sh
for pathname do
shift
set -- "$@" -v "$pathname:/opt/$pathname"
done
docker run "$@" fedora
Ambos seriam executados como
./script.sh path1 path2 path3 ...