listas de argumentos de compilação, contendo espaços em branco
-
03-07-2019 - |
Pergunta
Em bash pode-se escapar argumentos que contenham espaços em branco.
foo "a string"
Isso também funciona para argumentos para um comando ou função:
bar() {
foo "$@"
}
bar "a string"
Até aí tudo bem, mas o que se eu quiser manipular os argumentos antes de chamar foo
?
Isso não funciona:
bar() {
for arg in "$@"
do
args="$args \"prefix $arg\""
done
# Everything looks good ...
echo $args
# ... but it isn't.
foo $args
# foo "$args" would just be silly
}
bar a b c
Assim como você construir listas de argumentos quando os argumentos conter espaços em branco?
Solução
Há (pelo menos) duas maneiras de fazer isso:
-
Use uma matriz e expandi-la utilizando
"${array[@]}"
:bar() { local i=0 args=() for arg in "$@" do args[$i]="prefix $arg" ((++i)) done foo "${args[@]}" }
Então, o que aprendemos?
"${array[@]}"
é${array[*]}
que"$@"
é$*
. -
Ou se você não quer matrizes de uso que você precisa para uso
eval
:bar() { local args=() for arg in "$@" do args="$args \"prefix $arg\"" done eval foo $args }
Outras dicas
Aqui está uma versão mais curta que não requer o uso de um índice numérico:
(exemplo: a construção de argumentos para um comando find
)
dir=$1
shift
for f in "$@" ; do
args+=(-iname "*$f*")
done
find "$dir" "${args[@]}"
Você pode usar as matrizes apenas como você sugere, com um pequeno detalhe mudou. A linha que chama foo deve ler
foo "${args[@]}"
Eu tive um problema com este demasiado bem. Eu estava escrevendo um script para fazer backup dos arquivos importantes no meu computador windows (cygwin). Eu tentei a abordagem variedade também, e ainda tinha algumas questões. Não tenho certeza exatamente como eu fixa-lo, mas aqui está as partes do meu código que são importantes no caso de ele irá ajudá-lo.
WORK="d:\Work Documents\*"
# prompt and 7zip each file
for x in $SVN $WEB1 $WEB2 "$WORK" $GRAPHICS $W_SQL
do
echo "Add $x to archive? (y/n)"
read DO
if [ "$DO" == "y" ]; then
echo "compressing $x"
7zip a $W_OUTPUT "$x"
fi
echo ""
done