Tài liệu thứ 2 được Peter Mortensen trích dẫn trong bình luận của anh ấy về câu trả lời của Codesmith đã làm cho tôi thấy mọi thứ rõ ràng hơn nhiều. Tài liệu đó được viết bởi windowsinspired.com. Liên kết lặp lại: Cách tốt hơn để hiểu trích dẫn và thoát đối số dòng lệnh của Windows .
Một số thử nghiệm và sai sót khác dẫn đến nguyên tắc sau:
Thoát khỏi mọi dấu ngoặc kép "
bằng dấu mũ ^
. Nếu bạn muốn các nhân vật khác với ý nghĩa đặc biệt với vỏ lệnh của Windows (ví dụ <
, >
, |
, &
) được hiểu là ký tự thường xuyên thay vào đó, sau đó thoát khỏi chúng bằng dấu sót, quá.
Nếu bạn muốn foo chương trình của mình nhận văn bản dòng lệnh "a\"b c" > d
và chuyển hướng đầu ra của nó đến tệp out.txt , thì hãy khởi động chương trình của bạn như sau từ trình bao lệnh Windows:
foo ^"a\^"b c^" ^> d > out.txt
Nếu foo hiểu \"
là một dấu ngoặc kép theo nghĩa đen và mong đợi dấu ngoặc kép không thoát để phân tách các đối số bao gồm khoảng trắng, thì foo diễn giải lệnh là chỉ định một đối số a"b c
, một đối số >
và một đối số d
.
Nếu thay vào đó, foo diễn giải một dấu ngoặc kép kép ""
là một dấu ngoặc kép theo nghĩa đen, thì hãy bắt đầu chương trình của bạn bằng
foo ^"a^"^"b c^" ^> d > out.txt
Thông tin chi tiết chính từ tài liệu được trích dẫn là đối với trình bao lệnh Windows, một dấu ngoặc kép không thoát sẽ kích hoạt chuyển đổi giữa hai trạng thái có thể.
Một số thử nghiệm và lỗi khác ngụ ý rằng ở trạng thái ban đầu, chuyển hướng (đến tệp hoặc đường dẫn) được nhận dạng và dấu mũ ^
thoát khỏi dấu ngoặc kép và dấu mũ bị xóa khỏi đầu vào. Ở trạng thái khác, chuyển hướng không được nhận dạng và dấu mũ không thoát khỏi dấu ngoặc kép và không bị xóa. Chúng ta hãy gọi những trạng thái này tương ứng là 'bên ngoài' và 'bên trong'.
Nếu bạn muốn chuyển hướng đầu ra của lệnh, thì vỏ lệnh phải ở trạng thái bên ngoài khi nó đạt đến chuyển hướng, do đó phải có một số chẵn dấu ngoặc kép không thoát (bằng dấu mũ) trước chuyển hướng. foo "a\"b " > out.txt
sẽ không hoạt động - trình bao lệnh chuyển toàn bộ "a\"b " > out.txt
tới foo dưới dạng các đối số dòng lệnh kết hợp của nó, thay vì chỉ truyền "a\"b "
và chuyển hướng đầu ra đến out.txt .
foo "a\^"b " > out.txt
cũng sẽ không hoạt động, vì dấu mũ ^
gặp phải ở trạng thái bên trong nơi nó là một ký tự bình thường và không phải là một ký tự thoát, vì vậy "a\^"b " > out.txt
được chuyển cho foo .
Cách duy nhất (hy vọng) luôn hoạt động là giữ cho vỏ lệnh luôn ở trạng thái bên ngoài, vì khi đó chuyển hướng hoạt động.
Nếu bạn không cần chuyển hướng (hoặc các ký tự khác có ý nghĩa đặc biệt đối với vỏ lệnh), thì bạn có thể thực hiện mà không cần dấu mũ. Nếu foo hiểu \"
là một dấu ngoặc kép theo nghĩa đen, thì bạn có thể gọi nó là
foo "a\"b c"
Sau đó, foo nhận "a\"b c"
dưới dạng văn bản đối số kết hợp của nó và có thể diễn giải nó như một đối số duy nhất bằng a"b c
.
Bây giờ - cuối cùng - đến câu hỏi ban đầu. myscript '"test"'
được gọi từ trình bao lệnh Windows chuyển '"test"'
tới myscript . Rõ ràng myscript giải thích các dấu ngoặc kép và đơn là dấu phân cách đối số và loại bỏ chúng. Bạn cần phải tìm ra những gì myscript chấp nhận như một dấu ngoặc kép theo nghĩa đen và sau đó chỉ định điều đó trong lệnh của bạn, sử dụng ^
để thoát khỏi bất kỳ ký tự nào có ý nghĩa đặc biệt đối với trình bao lệnh Windows. Với điều đó myscript
cũng có sẵn trên Unix, có lẽ \"
đó là mẹo nhỏ. Thử
myscript \^"test\^"
hoặc, nếu bạn không cần chuyển hướng,
myscript \"test\"
myscript \"test\"