Windowsコマンドインタープリタで非常に奇妙な問題が発生しました。これはXPとWindows 7の両方で発生します。私の説明はPerlスクリプトにも当てはまりますが、この問題はコマンドラインでコマンドラインで任意の種類のプログラムを実行する場合に当てはまります。私が実行している場合このようにWindowsコマンドプロンプトで二重引用符をエスケープした副作用
use strict;
use warnings;
while (my $param = shift @ARGV) {
print "Param: [$param]\n";
}
- - 私は単にそれをパラメータとして見たものを出力するPerlスクリプトcheck-params.pl
を使用していますテストのために
perl check-params.pl "a b|<>" c^|^<^>cc
その後、出力は
[Param: a b|<>]
[Param: c|<>cc]
です
期待どおりです。特別な文字| <>は二重引用符でうまく動作しますが、引用符を外すと^でエスケープします。
二重引用符が
perl check-params.pl "a\" b|<>"
に引用されたのparamなどに添加した場合しかし、その後、私はエラーを取得する -
> was unexpected at this time.
しかし、二重引用符が後に特殊な文字を来る場合| <または>を入力しても問題ありません。
これを簡単に修正するには、特殊な| <>引用符で囲まれたパラメータの中に^を持つchar 例えば
perl check-params.pl "a\" b^|"
しかしだけでなく、エスケープされた二重引用符は特殊文字には影響しません| <>現在のパラメータにありますが、後続のパラメータ内のこれらの特殊文字に影響します。
例えば、私はこれを行う場合 -
(check-pipe.pl
は、単にパイプを受け取っ何を出力 -
use strict;
use warnings;
while (<STDIN>) {
print "PIPE RECEIVED ---> $_";
}
)
perl check-params.pl "aa \"bb" ccc | perl check-pipe.pl
を、出力がある -
Param: [aa "bb]
Param: [ccc]
Param: [|]
Param: [perl]
Param: [check-pipe.pl]
すなわち、それパイプを扱う|リテラル文字として使用され、配管は行われません。
この問題の経験をお持ちの方もいらっしゃいましたが、回避策はありますか?
Webログファイルを処理するためのPerlスクリプトをいくつか書いてあり、コマンドラインで引用符付きのパラメータ内を渡すregexを使います。正規表現には、| <>と二重引用符も付いている可能性がありますので、上記のように問題が発生しています。
ご協力いただきありがとうございます。
返信ありがとうございますが、これをXP SP3で試してみると、Perlスクリプトには2つのコマンドラインパラメータが表示されています。 | \「は特殊な文字の後に来るので、
'c"' is not recognized as an internal or external command,
operable program or batch file.
しかし
echo "a b|\"c"
作品 -
この問題は、Perlのに関連していない例えば
echo "a \"b|c"
はエラーを生成します。
Itコマンドインタープリタのバグでなければなりません。私はこれについてもっと知り、可能であれば回避策を見つけることに興味があります。この問題は、いくつかの便利なスクリプトの実行を駄目にします。コマンドインタプリタにとっては非常に目立つ問題です。私は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: -
例えば、走行用: -
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]
は、このように予想されるように、このコマンドラインは動作することを確認しました。スクリプトは、コマンドライン上の任意の数のパイプで動作します。
追加情報:
私は、これは、多くの回避策を使用して動作するように取得することができます見つける - 例えば^「ハリーは述べた一例であり、時にはあなたが使用しないように正規表現をrecraftすることができます。」と。特別なchar | <の前に2つの\ "シーケンスがある場合、問題は発生しません。コマンドを実行する前に、check-params.plとcheck-pipe.plを実行してPerlスクリプトにコマンドラインパラメータ例えば、私のOPへの上記の編集は、私のOPから修正したこれらのスクリプトを記述する。
正規表現をインタラクティブに入力すると、あなたのスクリプトがあなたのためにプロンプトを表示するのではなく、プロンプトを表示する方が便利な場合があります。コマンドライン。そうすれば、すべての特殊文字をエスケープする必要はありません。 –
多くの情報に感謝します。私は自分のOPでのテストから印象を受けていました\ "エスケープシーケンスでした。私は非常に多くのコマンドを持っているので、コマンドラインパラメータを入力することは現実的ではありません。それらをテキストファイルから読み込み、いくつかをコピーして一度にすべて実行することもできます(クイック編集モードでは右クリックしてコマンドウィンドウに貼り付けることができます) –