簡體   English   中英

在Windows命令提示符中轉義雙引號副作用

[英]Escaped Double Quote Side Effect in Windows Command Prompt

我遇到了Windows命令解釋器的一個非常奇怪的問題。 它出現在XP和Windows 7上。我的描述適用於Perl腳本,但是這個問題適用於在命令行上運行任何類型的程序,它接受命令行參數。

對於測試,我使用Perl腳本check-params.plcheck-params.pl輸出它看到的參數 -

use strict;
use warnings;
while (my $param = shift @ARGV) {
    print "Param: [$param]\n";
}

因此,如果我跑 -

perl check-params.pl "a b|<>" c^|^<^>cc

然后輸出是

[Param: a b|<>]
[Param: c|<>cc]

正如所料。 特殊的字符| <>在雙引號內工作正常,但在外部引號時,你用^來轉義它們。

但是,當引用的參數添加雙引號時,例如

perl check-params.pl "a\" b|<>"

然后我得到錯誤 -

> was unexpected at this time.

但如果雙引號出現特殊的char |之后 <或>,然后它工作正常。

你可以通過轉義特殊的|來輕松解決這個問題 <> char,帶引號參數內的^。 例如

perl check-params.pl "a\" b^|"

但是,轉義的雙引號不僅影響特殊字符| 當前參數中的<>但它會影響任何后續參數中的這些特殊字符。

例如,如果我這樣做 -

perl check-params.pl "aa \"bb" ccc | perl check-pipe.pl

(其中check-pipe.pl只輸出管道收到的內容 -

use strict;
use warnings;
while (<STDIN>) {
    print "PIPE RECEIVED ---> $_";
}

然后輸出是 -

Param: [aa "bb]
Param: [ccc]
Param: [|]
Param: [perl]
Param: [check-pipe.pl]

即它對待管道 作為文字字符,沒有管道發生。

有沒有人有這個問題的經驗,知道任何解決方法?

我編寫了一些用於處理Web日志文件的Perl腳本,並且使用了正則表達式,我在命令行上的一個引用的參數中傳遞。 正則表達式可能包含諸如|之類的字符 <>,它也可能有一個雙引號,我輸入為“。”因此上面的問題正在出現。

任何幫助非常感謝,謝謝。


感謝您的回復,但在XP SP3上嘗試此操作時,Perl腳本會看到兩個命令行參數。

這個問題與Perl無關,例如

echo "a \"b|c"

產生錯誤 -

'c"' is not recognized as an internal or external command,
operable program or batch file.

echo "a b|\"c"

工作,因為\\“來自特殊的char |。

它必須是命令解釋器中的錯誤。 我有興趣了解更多相關信息,並在可能的情況下找到解決方法。 這個問題困擾着運行一些有用的腳本。 對於命令解釋器來說,這是一個非常明顯的問題。 我也試過Windows 7,並且上面的回聲測試也出現了同樣的問題。


附加信息:

我更新了腳本check-params.pl和check-pipe.pl以提供更多有用的信息: -

check-params.pl: -

use strict;
use warnings;
while (my $param = shift @ARGV) {
    print "COMMAND LINE RECEIVED: [$param]\n";
}

check-pipe.pl: -

use strict;
use warnings;
while (<STDIN>) {
    print "PIPE RECEIVED: $_";
}

while (my $param = shift @ARGV) {
    print "COMMAND LINE RECEIVED: [$param]\n";
}

例如跑步: -

perl pl/utils/check-params.pl l1 l1-b l1-c | perl pl/utils/check-pipe.pl l2 l2-b | perl pl/utils/check-pipe.pl l3 l3-b | perl pl/utils/check-pipe.pl united arsenal rangers raith

產生輸出: -

PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1]
PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-b]
PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-c]
PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2]
PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2-b]
PIPE RECEIVED: COMMAND LINE RECEIVED: [l3]
PIPE RECEIVED: COMMAND LINE RECEIVED: [l3-b]
COMMAND LINE RECEIVED: [united]
COMMAND LINE RECEIVED: [arsenal]
COMMAND LINE RECEIVED: [rangers]
COMMAND LINE RECEIVED: [raith]

從而確認此命令行將按預期工作。 這些腳本可以在命令行上使用任意數量的管道。


附加信息:

我發現我可以使用多種解決方法來實現這一點 - 例如^“Harry提到的是一個例子。有時你可以重新制作正則表達式以避免使用”。 當在特殊char | <>之前有兩個“序列”時,問題就不會發生。在運行任何命令之前,我運行check-params.pl和check-pipe.pl來驗證Perl腳本將如何看到命令行參數,例如上面對我的OP的編輯描述了這些腳本,我從OP開始修改了這些腳本。

\\“中的雙引號被認為與初始雙引號相匹配,結束了引用的參數。要在引用參數中包含雙引號,請使用兩個雙引號:

perl check-params.pl "a"" b|<>"

應該產生你期望的結果,這取決於perl.exe如何解析命令行參數(我已經使用命令腳本測試,因為我沒有安裝Perl)。 您需要更改腳本,以便將“”而不是“”視為雙引號。

附加 :此命令行

echo "a \"b|c"

導致錯誤消息開始c" is not recognized這不是錯誤。

反斜杠不是轉義字符,因此命令行包含一個帶引號的字符串( "a \\" )后跟一個管道( | ),這使得其余的命令( c" )成為一個附加命令,來自echo命令的輸出通過管道輸出成。

如果你反而說

echo "a ""b|c"

然后只有一個帶引號的字符串( "a ""b|c" ),它將按預期工作。

不幸的是,我現在可以確認ActivePerl的命令行解析導致了

perl check-params.pl "a"" b|"

分為兩個參數。 您可能需要獲取整個命令行(如果有辦法在Perl中執行此操作)並自己解析它。

附加

perl check-params.pl ^"a\^" b^|c^"

產生預期的結果。 這可以通過轉義所有特殊字符(包括引號)來實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM