Thoát dấu ngoặc kép trong tham số


109

Trong Unix, tôi có thể chạy myscript '"test"'và tôi sẽ nhận được "test".

Trong Windows cmdtôi nhận được 'test'.

Làm cách nào để chuyển dấu ngoặc kép làm tham số? Tôi muốn biết cách thực hiện việc này theo cách thủ công từ một cmdcửa sổ để tôi không phải viết chương trình để kiểm tra chương trình của mình.


2
Đã nhiều năm kể từ khi tôi chạm vào máy tính Windows, nhưng ký tự thoát tiêu chuẩn (dấu gạch chéo ngược \) không hoạt động? ví dụmyscript \"test\"
Gazler 13/10/11

Không. Tôi nhận được \ test \. Tôi nghi ngờ đó là do các cửa sổ sử dụng \ thay vì / nên dấu gạch chéo ngược không thể được sử dụng như một bộ thoát. Nhưng tôi không thực sự biết.
Bryan Field

Không biết bạn đang sử dụng phiên bản Windows nào, nhưng \ "hoạt động tốt trên Windows 7 (Ultimate). Tuy nhiên, có một cách khác để làm điều đó, xử lý nhiều dấu ngoặc kép (tức là" "" trở thành "hoặc cái gì đó), nhưng tôi không thể tìm ra thời điểm và cách thức hoạt động.
Thợ mã

Câu trả lời:


22

Tôi không thể nhanh chóng tái tạo các hiện tượng: nếu tôi thử myscript '"test"'với một tệp hàng loạt myscript.batchứa chỉ @echo.%1hoặc thậm chí @echo.%~1, tôi nhận được tất cả các dấu ngoặc kép:'"test"'

Có lẽ bạn có thể thử ký tự thoát ^như thế này myscript '^"test^"':?


3
Sau đó, có thể câu trả lời cho câu hỏi này có thể giúp bạn thêm?
mousio 13/10/11

2
Ha! Tôi không bao giờ có thể đoán đó là wscriptlỗi của! Để nó cho Windows :)
Bryan Field

4
Trên thực tế ^ không làm việc cho tôi, nhưng \ đã làm, mỗi câu trả lời này: stackoverflow.com/questions/2403647/...
kalenjordan

26
Windows: hệ điều hành mà ở đó việc lấp đầy, mở rộng trình bao và bỏ thoát tham số được thực hiện bởi tệp thực thi được gọi thay vì trình bao. Bạn không bao giờ biết quy ước nào, nếu có, các danh hiệu thực thi được gọi.
binki

7
Đầu vào có giá trị: blog.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/… . Dấu mũ thực sự là ký tự thoát được lựa chọn cho cmd.
Peter - Phục hồi Monica

198

Một cách khác để thoát khỏi dấu ngoặc kép (mặc dù có lẽ không thích hợp), mà tôi thấy được sử dụng ở một số nơi nhất định là sử dụng nhiều dấu ngoặc kép . Với mục đích làm cho mã của người khác dễ đọc, tôi sẽ giải thích.

Đây là một tập hợp các quy tắc cơ bản:

  1. Khi không được bọc trong nhóm dụng dấu ngoặc kép, không gian thông số riêng biệt:
    program param1 param2 param 3sẽ vượt qua bốn thông số để program.exe:
         param1, param2, param, và 3.
  2. Một nhóm dụng dấu ngoặc kép bỏ qua không gian như tách giá trị khi đi qua các thông số cho các chương trình:
    program one two "three and more"sẽ vượt qua ba thông số để program.exe:
         one, two, và three and more.
  3. Bây giờ để giải thích một số nhầm lẫn:
  4. Nhóm xuất hiện liền kề trực tiếp đến văn bản không được bao bọc bởi hai dấu ngoặc kép tham gia vào một tham số dụng dấu ngoặc kép:
    hello"to the entire"worldđóng vai trò như một tham số: helloto the entireworld.
  5. Lưu ý: Quy tắc trước đó KHÔNG ngụ ý rằng hai nhóm được trích dẫn kép có thể xuất hiện trực tiếp liền kề với nhau.
  6. Bất kỳ dấu ngoặc kép nào ngay sau câu trích dẫn đóng đều được coi là (hoặc như một phần của) văn bản đơn giản không được bao bọc bên cạnh nhóm được trích dẫn kép, nhưng chỉ một dấu ngoặc kép:
    "Tim says, ""Hi!"""sẽ hoạt động như một tham số:Tim says, "Hi!"

Do đó, có ba loại dấu ngoặc kép khác nhau: dấu ngoặc kép mở, dấu ngoặc kép đóng và dấu ngoặc kép hoạt động như văn bản thuần túy.
Đây là sự cố của dòng khó hiểu cuối cùng đó:

"mở nhóm dấu ngoặc kép
T bên trong "" s
tôi bên trong "" s
m bên trong "" s
    bên trong "" s - dấu cách không tách biệt
s bên trong "" s
một bên trong "" s
y bên trong "" s
s bên trong "" s
, bên trong "" s
    bên trong "" s - dấu cách không tách biệt
"nhóm đóng dấu ngoặc kép
"trích dẫn trực tiếp theo sau gần hơn - hoạt động như văn bản đơn giản không được bao bọc:"
H bên ngoài "" s - được tham gia vào nhóm liền kề trước đó
tôi bên ngoài "" s - ...
! bên ngoài "" s - ...
"mở nhóm dấu ngoặc kép
"đóng nhóm dấu ngoặc kép
"trích dẫn trực tiếp theo sau gần hơn - hoạt động như văn bản đơn giản không được bao bọc:"

Do đó, văn bản kết hợp hiệu quả bốn nhóm ký tự (tuy nhiên, một nhóm không có gì):
Tim says,  là nhóm đầu tiên, được bao bọc để thoát khỏi khoảng trắng
"Hi!là nhóm thứ hai, không được bao bọc (không có khoảng cách)
 là nhóm thứ ba, nhóm dấu ngoặc kép không bao gồm gì
"là câu thứ tư, câu trích dẫn đóng chưa được bao bọc.

Như bạn có thể thấy, nhóm dấu ngoặc kép không có gì là cần thiết vì nếu không có nó, dấu ngoặc kép sau sẽ mở ra một nhóm trích dẫn kép thay vì hoạt động như văn bản thuần túy.

Từ điều này, có thể nhận ra rằng do đó, các dấu ngoặc kép bên trong và bên ngoài, ba dấu ngoặc kép hoạt động như một dấu ngoặc kép không thoát văn bản thuần túy:

"Tim nói với anh ấy," "" Chuyện gì đang xảy ra gần đây vậy? "" ""

sẽ in Tim said to him, "What's been happening lately?"như mong đợi. Do đó, ba dấu ngoặc kép luôn có thể được sử dụng một cách đáng tin cậy như một lối thoát.
Tuy nhiên, khi hiểu nó, bạn có thể lưu ý rằng bốn dấu ngoặc kép ở cuối có thể được giảm xuống chỉ còn hai vì về mặt kỹ thuật, nó đang thêm một nhóm dấu ngoặc kép trống không cần thiết khác.

Dưới đây là một số ví dụ để tắt nó:

chương trình ab REM gửi (a) và (b)
chương trình "" "a" "" REM gửi ("a")
chương trình "" "a b" "" REM gửi ("a) và (b")
chương trình "" "" Xin chào, "" "Mike nói." REM gửi ("Xin chào," Mike nói.)
chương trình "" a "" b "" c "" d "" REM gửi (abcd) vì các nhóm "" không bao gồm gì
chương trình "xin chào bạn" "" dấu ngoặc kép "" REM gửi (xin chào bạn đến "dấu ngoặc kép")
chương trình "" "" hello world "" REM gửi ("hello world")
chương trình "" "xin chào" thế giới "" REM gửi ("xin chào thế giới")
chương trình "" "xin chào" thế giới "" REM gửi ("xin chào) và (thế giới")
chương trình "xin chào" "thế giới" "" REM gửi (xin chào "thế giới")
chương trình "xin chào" "" thế giới "" REM gửi (xin chào "thế giới")

Lưu ý cuối cùng: Tôi không đọc bất kỳ điều này từ bất kỳ hướng dẫn nào - tôi đã nghĩ ra tất cả bằng cách thử nghiệm. Do đó, lời giải thích của tôi có thể không đúng trong nội bộ. Tuy nhiên, tất cả các ví dụ trên đều đánh giá như đã cho, do đó xác nhận (nhưng không chứng minh) lý thuyết của tôi.

Tôi đã thử nghiệm điều này trên Windows 7, 64bit chỉ sử dụng các lệnh gọi * .exe có truyền tham số (không phải * .bat, nhưng tôi sẽ cho rằng nó hoạt động giống nhau).


11
+1, nhưng lưu ý rằng hành vi này phụ thuộc vào ứng dụng. Trong Windows, mỗi ứng dụng phân tích cú pháp các tham số dòng lệnh của riêng nó. Tôi tin rằng hành vi bạn đang mô tả là của thư viện C tiêu chuẩn của Microsoft, mà tôi nghĩ rằng nó cũng bị sao chép bởi hầu hết các trình biên dịch Windows C khác.
Harry Johnston

3
Nhiều lỗi trong bài kiểm tra cuối cùng của bạn. chương trình "" "ab" "" -> ("ab"), chương trình "xin chào" "" dấu ngoặc kép "" -> (xin chào "dấu ngoặc kép), chương trình" "" "xin chào thế giới" "-> (" Xin chào) (thế giới), chương trình "" "xin chào" thế giới "" -> ("xin chào) (thế giới), chương trình" "" xin chào "thế giới" "-> (" xin chào thế giới), chương trình "xin chào" "" thế giới "" - > (xin chào "thế giới)
Thomson

46
... Tất cả những gì tôi có thể nói là, các tệp hàng loạt của Windows có vấn đề. Đây là câu nói thoát khỏi dấu ngoặc kép , vì Chúa; nó không nhất thiết phải là một loại khoa học tên lửa.
James Ko

4
@JamesKo Tôi không thể đồng ý hơn. Sự vô lý và mâu thuẫn phức tạp của dòng lệnh Windows không bao giờ khiến tôi tức giận. Ai đã thiết kế ra thứ rác này? Ôi, những giờ đã lãng phí trong những năm qua! Unix quá dễ dàng và có nhiều ý nghĩa khi so sánh.
Carlos A. Ibarra


24

Thử cái này:

myscript """test"""

"" thoát thành một "trong tham số.


1
Điều đó không hoàn toàn chính xác. Hãy thử myscript """test test"""và nó không hoạt động (tham số đầu tiên được chuyển giao dưới dạng "test. Thông thường, bạn cần ba dấu ngoặc kép: myscript """"test test""Tuy nhiên, dấu ngoặc kép ở cuối có thể bị bỏ qua.
Ignitor

Điều gì sẽ xảy ra nếu tôi cần xóa tất cả các dấu ngoặc kép ở đây và đặt giá trị tham số vào một chuỗi được sử dụng trong bộ lọc truy vấn chọn? Ai đó có thể giúp đỡ?
SFDC_Learner

2
Có thể không đúng cho câu hỏi này, nhưng điều này đã giúp tôi khi tôi cần chuyển char **argvtừ trình khởi chạy C của mình sang một quy trình khác bằng cách sử dụng các chức năng như spawnhoặc exec. Cảm ơn bạn. :-)
virgo47

2

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" > dvà 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.txtsẽ không hoạt động - trình bao lệnh chuyển toàn bộ "a\"b " > out.txttớ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.txtcũ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 đó myscriptcũ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\"

CẢM ƠN BẠN! Tôi đang đập đầu vào tường khi cố chạy một vbscript với văn bản nhắc cmd được lặp lại thành văn bản nhắc cmd - tôi thừa hưởng điều này - và không thể tìm ra cách thoát khỏi dấu ngoặc kép.
PopeDarren

0

Tôi đang gọi powershell từ cmd và chuyển các dấu ngoặc kép và không thoát ở đây hoạt động. Dấu ngoặc kép hoạt động để thoát khỏi dấu ngoặc kép trên Win 10 surface pro này.

>powershell.exe "echo la`"" >> test
>type test
la"

Dưới đây là kết quả mà tôi nhận được để các nhân vật khác thoát khỏi dấu ngoặc kép:

la\
la^
la
la~

Sử dụng một trích dẫn khác để thoát khỏi một trích dẫn dẫn đến không có dấu ngoặc kép. Như bạn có thể thấy, bản thân các ký tự đã được nhập, nhưng không thoát khỏi dấu ngoặc kép.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.