Ho provato molte soluzioni diverse, una buona risorsa che include informazioni di base e alternative è ad esempio BashFAQ / 096 sul Wiki di Greg (aka. GreyCat) . Complessivamente ho trovato i due seguenti i più leggibili (da quelli funzionanti):
Da Bash 4.4 (per quanto ne so dalle NEWS ) è possibile utilizzare l' espansione dei parametri in @Q questo modo:
adb sh -c "other_tool -a -b ${*@Q}"
Nota che io uso $*qui invece che $@perché vuoi "other_tool -a -b ${*@Q}"essere una stringa singola anziché una stringa per argomento passato.
Se vuoi fare lo stesso con una variabile array bash, avrai bisogno della sintassi ${ARRAY[*]@Q}(tra virgolette).
Se non hai Bash 4.4 o versione successiva o non sei sicuro, questa è la mia soluzione preferita:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
Si noti che qui è necessario utilizzare "$@"anziché $@o "$*"o $*perché non si desidera la suddivisione delle parole all'interno degli argomenti, quindi le varianti senza virgolette non possono essere utilizzate e si desidera conservare il numero di argomenti, quindi "$*"non può essere utilizzato come si unirebbe tutti gli argomenti in una singola stringa. La funzione restituisce quindi tutti gli argomenti in una singola stringa.
Se non ti interessa lo spazio aggiuntivo davanti al primo argomento, puoi modificare la printfstringa di formato in " %q"e rimuovere la separatorvariabile. Oppure puoi usare il one-liner della risposta di Gordon Davissons .
Queste soluzioni funzionano con tutti i casi che ho potuto trovare, in particolare:
- Nessun argomento:
escapeBashArgs→ niente
- Argomenti vuoti:
escapeBashArgs "" ""→'' ''
- Argomenti con solo spazi:
escapeBashArgs " " " "→ ' ' ' 'o \ \ \ \ \( l'ultimo spazio viene mangiato da questo renderer di siti )
- Argomenti con spaziatura speciale e newline :
escapeBashArgs "a b" c\ d "arg with
newline"→ 'a b' 'c d' $'arg with\nnewline'o a\ \ \ \ \ \ b c\ d $'arg with\nnewline'( la newline è tra withe newline, in altre posizioni è a causa del ritorno a capo su questo sito )
- Argomenti con caratteri speciali:
escapeBashArgs '$"'\''({:})'→ '$"'\''({:})'o\$\"\'\(\{:\}\)
- Esempio dalla risposta di jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'ox/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(Testato con GNU bash 5.0.3 (1)-release).