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 printf
sequência de formatação para " %q"
e remover a separator
variá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 with
e 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).)