A linha no seu código weka $1 ${search["$1"]}
está sendo sujeita a divisão de shell.
Se você não alterou a variável $IFS
essa divisão irá acontecer na espaço guia nova linha .
A linha é expandida para:
weka $1 ${search["$1"]}
weka a -search "a params" -search "other a params"
Mas, ao ser dividido, conforme descrito acima, é isso que significa:
<weka> <a> <-search> <"a> <params"> <-search> <"other> <a> <params">
Você pode ver exatamente o mesmo printf anterior na linha:
$ printf '<%s> ' weka $1 ${search["$1"]}; echo
<weka> <a> <-search> <"a> <params"> <-search> <"other> <a> <params">
Isso ficará melhor se as variáveis forem citadas corretamente:
$ printf '<%s> ' weka "$1" "${search["$1"]}"; echo
<weka> <a> <-search "a params" -search "other a params">
Mas isso não é o que você quer. Você precisa dividi-lo, mas não em espaços simples.
O que fazer?
Existem duas soluções:
Dividir manualmente
Use algum caractere como #
para marcar manualmente a posição de divisão:
search=( ["a"]='-search#a params#-search#other a params' ["b"]='-search#just these params' )
Em seguida, diga ao bash qual é o caractere usado para dividir com IFS
, para dividir a string em uma nova matriz b
:
IFS='#'
b=( ${search["a"]} )
printf '<%s> ' "${b[@]}"; echo
Que produz:
<-search> <a params> <-search> <other a params>
A divisão exata que você deseja.
O único problema é que IFS
foi alterado, mas podemos resolver isso em uma função fazendo IFS
local:
callsplit(){
local IFS='#'
b=( ${search["$1"]} )
weka "$1" "${b[@]}"
}
Use Eval
A outra solução é usar o eval para analisar novamente a linha de comando, para que o shell possa dividi-lo, assim como o modo comum de os shells dividirem as linhas.
O valor da pesquisa variável será como você definiu:
search=( ["a"]='-search "a params" -search "other a params"'
["b"]='-search "just these params"' )
Mas vamos expandir a linha de execução com eval:
eval weka "$1" "${search["$1"]}"
Se você quiser ver como a linha é expandida, use:
$ eval printf "'<%s> '" weka "$1" "${search["$1"]}"; echo
<weka> <a> <-search> <a params> <-search> <other a params>
O script inteiro será:
#!/bin/bash
declare -A search
search+=( ["a"]='-search "a params" -search "other a params"')
search+=( ["b"]='-search "just these params"' )
call_thing() {
eval weka "$1" "${search["$1"]}"
} # <-- closing brace for the function
call_thing "a"
Nota: Isso funcionará corretamente supondo que os valores da pesquisa estejam dentro do script (nenhum invasor externo poderia defini-los) e esses valores são citados como "linha de comando" de um shell comum .
Aviso : O uso de eval pode permitir que dados como uma string sejam convertidos em código como um comando. Neste script específico, esta linha:
call_thing "a; touch new_file"
Será executado o comando touch new_file
. Mas qualquer outro comando também pode ser executado. Tenha cuidado, muito cuidado com o que você alimenta para eval
.
rm -r /
. O comando eval
não é mais poderoso que qualquer um deles. Apenas tenha cuidado.