Tentei muitas soluções diferentes, um bom recurso, incluindo informações básicas e alternativas, é, por exemplo, o BashFAQ / 096 no Wiki de Greg (também conhecido como GreyCat) . No total, achei os dois seguintes os mais legíveis (dos que estão em funcionamento):
Desde o Bash 4.4 (até onde pude ver no NEWS ), é possível usar a expansão de parâmetros @Q como esta:
adb sh -c "other_tool -a -b ${*@Q}"
Observe que eu uso $*aqui em vez de, $@porque você deseja "other_tool -a -b ${*@Q}"ser uma única sequência em vez de uma sequência por argumento passado.
Se você quiser fazer o mesmo com uma variável do array bash , precisará da sintaxe ${ARRAY[*]@Q}(entre aspas).
Se você não tem o Bash 4.4 ou posterior disponível ou não tem certeza, esta é minha solução preferida:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
Observe que aqui você precisa usar em "$@"vez de $@ou "$*"ou $*porque não deseja dividir palavras nos argumentos, portanto, as variantes sem citação não podem ser usadas, e você deseja que o número de argumentos seja preservado, portanto "$*"não pode ser usado, pois todos os argumentos para uma única sequência. A função retorna todos os argumentos em uma única sequência.
Se você não se importa com o espaço adicional na frente do primeiro argumento, pode alterar a printfsequência de formatação para " %q"e remover a separatorvariável. Ou você pode usar o verso da resposta de Gordon Davissons .
Essas soluções funcionam com todos os casos que eu pude apresentar, especialmente:
- Sem argumentos:
escapeBashArgs→ nada
- Argumentos vazios:
escapeBashArgs "" ""→'' ''
- Argumentos com apenas espaços:
escapeBashArgs " " " "→ ' ' ' 'ou \ \ \ \ \( o último espaço é consumido por este renderizador de sites )
- Argumentos com espaçamento especial e novas linhas:
escapeBashArgs "a b" c\ d "arg with
newline"→ 'a b' 'c d' $'arg with\nnewline'ou a\ \ \ \ \ \ b c\ d $'arg with\nnewline'( a nova linha está entre withe newline, em outras posições, é devido ao agrupamento de linhas neste site )
- Argumentos com caracteres especiais:
escapeBashArgs '$"'\''({:})'→ '$"'\''({:})'ou\$\"\'\(\{:\}\)
- Exemplo da resposta jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'oux/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(Testado com o lançamento do GNU bash 5.0.3 (1).)