Probé muchas soluciones diferentes, un buen recurso que incluye información de fondo y alternativas es, por ejemplo, BashFAQ / 096 en el Wiki de Greg (también conocido como GreyCat) . En total, encontré que los dos siguientes son los más legibles (de los que funcionan):
Desde Bash 4.4 (por lo que pude ver en las NOTICIAS ) es posible usar la expansión de parámetros de @Q
esta manera:
adb sh -c "other_tool -a -b ${*@Q}"
Tenga en cuenta que uso $*
aquí en lugar de $@
porque desea "other_tool -a -b ${*@Q}"
ser una sola cadena en lugar de una cadena por argumento pasado.
Si desea hacer lo mismo con una variable de matriz bash , necesitaría la sintaxis ${ARRAY[*]@Q}
(entre comillas).
Si no tiene Bash 4.4 o posterior disponible o no está seguro, esta es mi solución preferida:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
Tenga en cuenta que aquí se necesita para usar "$@"
en lugar de $@
o "$*"
, o $*
porque no desea que la división de palabras dentro de los argumentos, por lo que las variantes sin citar no se puede utilizar, y desea que el número de argumentos que se conserva, por lo que "$*"
no se puede utilizar ya que se uniría Todos los argumentos a una sola cadena. La función luego devuelve todos los argumentos en una sola cadena.
Si no le importa el espacio adicional delante del primer argumento, puede cambiar la printf
cadena de formato " %q"
y eliminar la separator
variable. O puede usar la respuesta de Gordon Davisson .
Estas soluciones funcionan con todos los casos que se me ocurrieron, especialmente:
- Sin argumentos:
escapeBashArgs
→ nada
- Argumentos vacíos:
escapeBashArgs "" ""
→'' ''
- Argumentos con solo espacios:
escapeBashArgs " " " "
→ ' ' ' '
o \ \ \ \ \
( el último espacio lo ocupa el renderizador de este sitio )
- Argumentos con espacios especiales y líneas nuevas:
escapeBashArgs "a b" c\ d "arg with
newline"
→ 'a b' 'c d' $'arg with\nnewline'
o a\ \ \ \ \ \ b c\ d $'arg with\nnewline'
( la línea nueva está entre with
y newline
, en otras posiciones, se debe al ajuste de línea en este sitio )
- Argumentos con caracteres especiales:
escapeBashArgs '$"'\''({:})'
→ '$"'\''({:})'
o\$\"\'\(\{:\}\)
- Ejemplo de respuesta jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'
ox/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(Probado con GNU bash 5.0.3 (1) -release.)