Tôi đã thử nhiều giải pháp khác nhau, một nguồn tài nguyên tốt bao gồm thông tin cơ bản và các giải pháp thay thế là ví dụ BashFAQ / 096 trên Wiki của Greg (hay còn gọi là GreyCat) . Nhìn chung, tôi thấy hai cái sau là dễ đọc nhất (từ những cái đang hoạt động):
Vì Bash 4.4 (theo như tôi có thể nói từ TIN TỨC ) nên có thể sử dụng mở rộng tham số @Q
như thế này:
adb sh -c "other_tool -a -b ${*@Q}"
Lưu ý rằng tôi sử dụng $*
ở đây thay $@
vì bởi vì bạn muốn "other_tool -a -b ${*@Q}"
trở thành một chuỗi thay vì một chuỗi cho mỗi đối số được truyền.
Nếu bạn muốn làm tương tự với một biến bash mảng bạn sẽ cần cú pháp ${ARRAY[*]@Q}
(trong dấu ngoặc kép).
Nếu bạn không có sẵn Bash 4.4 trở lên hoặc không chắc chắn, đây là giải pháp ưa thích của tôi:
function escapeBashArgs() {
local arg separator=""
for arg
do
printf "%s%q" "$separator" "$arg"
separator=" "
done
}
adb sh -c "other_tool -a -b $(escapeBashArgs "$@")"
Lưu ý rằng ở đây bạn cần sử dụng "$@"
thay vì $@
hoặc "$*"
hoặc$*
vì bạn không muốn chia từ trong các đối số, do đó, các biến thể không trích dẫn không thể được sử dụng và bạn muốn giữ nguyên số lượng đối số, vì vậy "$*"
không thể sử dụng vì nó sẽ tham gia tất cả các đối số cho một chuỗi. Hàm sau đó trả về tất cả các đối số trong một chuỗi.
Nếu bạn không quan tâm đến không gian bổ sung phía trước đối số đầu tiên, bạn có thể thay đổi printf
chuỗi định dạng thành " %q"
và xóa separator
biến. Hoặc bạn có thể sử dụng một lớp lót từ câu trả lời của Gordon Davissons .
Giải pháp này hoạt động với tất cả các trường hợp tôi có thể đưa ra, đặc biệt là:
- Không có đối số:
escapeBashArgs
→ không có gì
- Đối số trống:
escapeBashArgs "" ""
→'' ''
- Các đối số chỉ có khoảng trắng:
escapeBashArgs " " " "
→ ' ' ' '
hoặc \ \ \ \ \
( không gian cuối cùng được ăn bởi trình kết xuất trang web này )
- Các đối số có khoảng cách và dòng mới đặc biệt:
escapeBashArgs "a b" c\ d "arg with
newline"
→ 'a b' 'c d' $'arg with\nnewline'
hoặc a\ \ \ \ \ \ b c\ d $'arg with\nnewline'
( dòng mới nằm giữa with
và newline
, trên các vị trí khác, đó là do gói dòng trên trang web này )
- Đối số với các ký tự đặc biệt:
escapeBashArgs '$"'\''({:})'
→ '$"'\''({:})'
hoặc\$\"\'\(\{:\}\)
- Ví dụ từ câu trả lời của jcayzacs :
escapeBashArgs x/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
→ 'x/ "b"/aaaaa/'\''xxx yyyy'\''/zz"offf"'
hoặcx/\ \ \"b\"/aaaaa/\'xxx\ yyyy\'/zz\"offf\"
(Đã thử nghiệm với GNU bash 5.0.3 (1) -release.)