Wypróbowałem wiele różnych rozwiązań, dobrym źródłem informacji, w tym podstawowymi informacjami i alternatywami, jest na przykład BashFAQ / 096 na Wiki Grega (alias. GreyCat) . W sumie dwa następujące są najbardziej czytelne (z działających):
Od wersji Bash 4.4 (o ile mogłem powiedzieć z AKTUALNOŚCI ) możliwe jest użycie rozszerzenia parametrów w @Q następujący sposób:
adb sh -c "other_tool -a -b ${*@Q}"
Zauważ, że używam $*tutaj zamiast, $@ponieważ chcesz "other_tool -a -b ${*@Q}"być jednym ciągiem zamiast jednego ciągu na przekazany argument.
Jeśli chcesz zrobić to samo ze zmienną tablicy bash , potrzebujesz składni ${ARRAY[*]@Q}(w cudzysłowach).
Jeśli nie masz dostępnej wersji Bash 4.4 lub nowszej lub nie masz pewności, oto moje preferowane rozwiązanie:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
Zauważ, że tutaj musisz użyć "$@"zamiast $@lub "$*"lub $*ponieważ nie chcesz dzielenia słów w argumentach, więc nie można użyć wariantów bez cudzysłowu i chcesz zachować liczbę argumentów, więc "$*"nie można użyć, jak by się przyłączyła wszystkie argumenty w jednym ciągu. Następnie funkcja zwraca wszystkie argumenty w jednym ciągu.
Jeśli nie zależy ci na dodatkowej spacji przed pierwszym argumentem, możesz zmienić printfciąg formatu na " %q"i usunąć separatorzmienną. Lub możesz użyć jednowierszowej odpowiedzi Gordona Davissona .
Te rozwiązania działają ze wszystkimi przypadkami, które mógłbym wymyślić, w szczególności:
- Brak argumentów:
escapeBashArgs→ nic
- Puste argumenty:
escapeBashArgs "" ""→'' ''
- Argumenty zawierające tylko spacje:
escapeBashArgs " " " "→ ' ' ' 'lub \ \ \ \ \( ostatnia przestrzeń jest zjedzona przez ten renderer stron )
- Argumenty ze specjalnymi odstępami i nowymi liniami:
escapeBashArgs "a b" c\ d "arg with
newline"→ 'a b' 'c d' $'arg with\nnewline'lub a\ \ \ \ \ \ b c\ d $'arg with\nnewline'( nowa linia znajduje się pomiędzy withi newline, w innych pozycjach wynika z zawijania linii na tej stronie )
- Argumenty ze znakami specjalnymi:
escapeBashArgs '$"'\''({:})'→ '$"'\''({:})'lub\$\"\'\(\{:\}\)
- Przykład z odpowiedzi jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'lubx/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(Testowane z wydaniem GNU bash 5.0.3 (1).)